15796c8dcSSimon Schubert /* ELF executable support for BFD.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright 1993-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of BFD, the Binary File Descriptor library.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program; if not, write to the Free Software
195796c8dcSSimon Schubert Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
205796c8dcSSimon Schubert MA 02110-1301, USA. */
215796c8dcSSimon Schubert
225796c8dcSSimon Schubert
235796c8dcSSimon Schubert /*
245796c8dcSSimon Schubert SECTION
255796c8dcSSimon Schubert ELF backends
265796c8dcSSimon Schubert
275796c8dcSSimon Schubert BFD support for ELF formats is being worked on.
285796c8dcSSimon Schubert Currently, the best supported back ends are for sparc and i386
295796c8dcSSimon Schubert (running svr4 or Solaris 2).
305796c8dcSSimon Schubert
315796c8dcSSimon Schubert Documentation of the internals of the support code still needs
325796c8dcSSimon Schubert to be written. The code is changing quickly enough that we
335796c8dcSSimon Schubert haven't bothered yet. */
345796c8dcSSimon Schubert
355796c8dcSSimon Schubert /* For sparc64-cross-sparc32. */
365796c8dcSSimon Schubert #define _SYSCALL32
375796c8dcSSimon Schubert #include "sysdep.h"
385796c8dcSSimon Schubert #include "bfd.h"
395796c8dcSSimon Schubert #include "bfdlink.h"
405796c8dcSSimon Schubert #include "libbfd.h"
415796c8dcSSimon Schubert #define ARCH_SIZE 0
425796c8dcSSimon Schubert #include "elf-bfd.h"
435796c8dcSSimon Schubert #include "libiberty.h"
445796c8dcSSimon Schubert #include "safe-ctype.h"
45*ef5ccd6cSJohn Marino #include "elf-linux-psinfo.h"
465796c8dcSSimon Schubert
47cf7f2e2dSJohn Marino #ifdef CORE_HEADER
48cf7f2e2dSJohn Marino #include CORE_HEADER
49cf7f2e2dSJohn Marino #endif
50cf7f2e2dSJohn Marino
515796c8dcSSimon Schubert static int elf_sort_sections (const void *, const void *);
525796c8dcSSimon Schubert static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
535796c8dcSSimon Schubert static bfd_boolean prep_headers (bfd *);
545796c8dcSSimon Schubert static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
555796c8dcSSimon Schubert static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
565796c8dcSSimon Schubert static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
575796c8dcSSimon Schubert file_ptr offset);
585796c8dcSSimon Schubert
595796c8dcSSimon Schubert /* Swap version information in and out. The version information is
605796c8dcSSimon Schubert currently size independent. If that ever changes, this code will
615796c8dcSSimon Schubert need to move into elfcode.h. */
625796c8dcSSimon Schubert
635796c8dcSSimon Schubert /* Swap in a Verdef structure. */
645796c8dcSSimon Schubert
655796c8dcSSimon Schubert void
_bfd_elf_swap_verdef_in(bfd * abfd,const Elf_External_Verdef * src,Elf_Internal_Verdef * dst)665796c8dcSSimon Schubert _bfd_elf_swap_verdef_in (bfd *abfd,
675796c8dcSSimon Schubert const Elf_External_Verdef *src,
685796c8dcSSimon Schubert Elf_Internal_Verdef *dst)
695796c8dcSSimon Schubert {
705796c8dcSSimon Schubert dst->vd_version = H_GET_16 (abfd, src->vd_version);
715796c8dcSSimon Schubert dst->vd_flags = H_GET_16 (abfd, src->vd_flags);
725796c8dcSSimon Schubert dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx);
735796c8dcSSimon Schubert dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt);
745796c8dcSSimon Schubert dst->vd_hash = H_GET_32 (abfd, src->vd_hash);
755796c8dcSSimon Schubert dst->vd_aux = H_GET_32 (abfd, src->vd_aux);
765796c8dcSSimon Schubert dst->vd_next = H_GET_32 (abfd, src->vd_next);
775796c8dcSSimon Schubert }
785796c8dcSSimon Schubert
795796c8dcSSimon Schubert /* Swap out a Verdef structure. */
805796c8dcSSimon Schubert
815796c8dcSSimon Schubert void
_bfd_elf_swap_verdef_out(bfd * abfd,const Elf_Internal_Verdef * src,Elf_External_Verdef * dst)825796c8dcSSimon Schubert _bfd_elf_swap_verdef_out (bfd *abfd,
835796c8dcSSimon Schubert const Elf_Internal_Verdef *src,
845796c8dcSSimon Schubert Elf_External_Verdef *dst)
855796c8dcSSimon Schubert {
865796c8dcSSimon Schubert H_PUT_16 (abfd, src->vd_version, dst->vd_version);
875796c8dcSSimon Schubert H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
885796c8dcSSimon Schubert H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
895796c8dcSSimon Schubert H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
905796c8dcSSimon Schubert H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
915796c8dcSSimon Schubert H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
925796c8dcSSimon Schubert H_PUT_32 (abfd, src->vd_next, dst->vd_next);
935796c8dcSSimon Schubert }
945796c8dcSSimon Schubert
955796c8dcSSimon Schubert /* Swap in a Verdaux structure. */
965796c8dcSSimon Schubert
975796c8dcSSimon Schubert void
_bfd_elf_swap_verdaux_in(bfd * abfd,const Elf_External_Verdaux * src,Elf_Internal_Verdaux * dst)985796c8dcSSimon Schubert _bfd_elf_swap_verdaux_in (bfd *abfd,
995796c8dcSSimon Schubert const Elf_External_Verdaux *src,
1005796c8dcSSimon Schubert Elf_Internal_Verdaux *dst)
1015796c8dcSSimon Schubert {
1025796c8dcSSimon Schubert dst->vda_name = H_GET_32 (abfd, src->vda_name);
1035796c8dcSSimon Schubert dst->vda_next = H_GET_32 (abfd, src->vda_next);
1045796c8dcSSimon Schubert }
1055796c8dcSSimon Schubert
1065796c8dcSSimon Schubert /* Swap out a Verdaux structure. */
1075796c8dcSSimon Schubert
1085796c8dcSSimon Schubert void
_bfd_elf_swap_verdaux_out(bfd * abfd,const Elf_Internal_Verdaux * src,Elf_External_Verdaux * dst)1095796c8dcSSimon Schubert _bfd_elf_swap_verdaux_out (bfd *abfd,
1105796c8dcSSimon Schubert const Elf_Internal_Verdaux *src,
1115796c8dcSSimon Schubert Elf_External_Verdaux *dst)
1125796c8dcSSimon Schubert {
1135796c8dcSSimon Schubert H_PUT_32 (abfd, src->vda_name, dst->vda_name);
1145796c8dcSSimon Schubert H_PUT_32 (abfd, src->vda_next, dst->vda_next);
1155796c8dcSSimon Schubert }
1165796c8dcSSimon Schubert
1175796c8dcSSimon Schubert /* Swap in a Verneed structure. */
1185796c8dcSSimon Schubert
1195796c8dcSSimon Schubert void
_bfd_elf_swap_verneed_in(bfd * abfd,const Elf_External_Verneed * src,Elf_Internal_Verneed * dst)1205796c8dcSSimon Schubert _bfd_elf_swap_verneed_in (bfd *abfd,
1215796c8dcSSimon Schubert const Elf_External_Verneed *src,
1225796c8dcSSimon Schubert Elf_Internal_Verneed *dst)
1235796c8dcSSimon Schubert {
1245796c8dcSSimon Schubert dst->vn_version = H_GET_16 (abfd, src->vn_version);
1255796c8dcSSimon Schubert dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt);
1265796c8dcSSimon Schubert dst->vn_file = H_GET_32 (abfd, src->vn_file);
1275796c8dcSSimon Schubert dst->vn_aux = H_GET_32 (abfd, src->vn_aux);
1285796c8dcSSimon Schubert dst->vn_next = H_GET_32 (abfd, src->vn_next);
1295796c8dcSSimon Schubert }
1305796c8dcSSimon Schubert
1315796c8dcSSimon Schubert /* Swap out a Verneed structure. */
1325796c8dcSSimon Schubert
1335796c8dcSSimon Schubert void
_bfd_elf_swap_verneed_out(bfd * abfd,const Elf_Internal_Verneed * src,Elf_External_Verneed * dst)1345796c8dcSSimon Schubert _bfd_elf_swap_verneed_out (bfd *abfd,
1355796c8dcSSimon Schubert const Elf_Internal_Verneed *src,
1365796c8dcSSimon Schubert Elf_External_Verneed *dst)
1375796c8dcSSimon Schubert {
1385796c8dcSSimon Schubert H_PUT_16 (abfd, src->vn_version, dst->vn_version);
1395796c8dcSSimon Schubert H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
1405796c8dcSSimon Schubert H_PUT_32 (abfd, src->vn_file, dst->vn_file);
1415796c8dcSSimon Schubert H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
1425796c8dcSSimon Schubert H_PUT_32 (abfd, src->vn_next, dst->vn_next);
1435796c8dcSSimon Schubert }
1445796c8dcSSimon Schubert
1455796c8dcSSimon Schubert /* Swap in a Vernaux structure. */
1465796c8dcSSimon Schubert
1475796c8dcSSimon Schubert void
_bfd_elf_swap_vernaux_in(bfd * abfd,const Elf_External_Vernaux * src,Elf_Internal_Vernaux * dst)1485796c8dcSSimon Schubert _bfd_elf_swap_vernaux_in (bfd *abfd,
1495796c8dcSSimon Schubert const Elf_External_Vernaux *src,
1505796c8dcSSimon Schubert Elf_Internal_Vernaux *dst)
1515796c8dcSSimon Schubert {
1525796c8dcSSimon Schubert dst->vna_hash = H_GET_32 (abfd, src->vna_hash);
1535796c8dcSSimon Schubert dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
1545796c8dcSSimon Schubert dst->vna_other = H_GET_16 (abfd, src->vna_other);
1555796c8dcSSimon Schubert dst->vna_name = H_GET_32 (abfd, src->vna_name);
1565796c8dcSSimon Schubert dst->vna_next = H_GET_32 (abfd, src->vna_next);
1575796c8dcSSimon Schubert }
1585796c8dcSSimon Schubert
1595796c8dcSSimon Schubert /* Swap out a Vernaux structure. */
1605796c8dcSSimon Schubert
1615796c8dcSSimon Schubert void
_bfd_elf_swap_vernaux_out(bfd * abfd,const Elf_Internal_Vernaux * src,Elf_External_Vernaux * dst)1625796c8dcSSimon Schubert _bfd_elf_swap_vernaux_out (bfd *abfd,
1635796c8dcSSimon Schubert const Elf_Internal_Vernaux *src,
1645796c8dcSSimon Schubert Elf_External_Vernaux *dst)
1655796c8dcSSimon Schubert {
1665796c8dcSSimon Schubert H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
1675796c8dcSSimon Schubert H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
1685796c8dcSSimon Schubert H_PUT_16 (abfd, src->vna_other, dst->vna_other);
1695796c8dcSSimon Schubert H_PUT_32 (abfd, src->vna_name, dst->vna_name);
1705796c8dcSSimon Schubert H_PUT_32 (abfd, src->vna_next, dst->vna_next);
1715796c8dcSSimon Schubert }
1725796c8dcSSimon Schubert
1735796c8dcSSimon Schubert /* Swap in a Versym structure. */
1745796c8dcSSimon Schubert
1755796c8dcSSimon Schubert void
_bfd_elf_swap_versym_in(bfd * abfd,const Elf_External_Versym * src,Elf_Internal_Versym * dst)1765796c8dcSSimon Schubert _bfd_elf_swap_versym_in (bfd *abfd,
1775796c8dcSSimon Schubert const Elf_External_Versym *src,
1785796c8dcSSimon Schubert Elf_Internal_Versym *dst)
1795796c8dcSSimon Schubert {
1805796c8dcSSimon Schubert dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
1815796c8dcSSimon Schubert }
1825796c8dcSSimon Schubert
1835796c8dcSSimon Schubert /* Swap out a Versym structure. */
1845796c8dcSSimon Schubert
1855796c8dcSSimon Schubert void
_bfd_elf_swap_versym_out(bfd * abfd,const Elf_Internal_Versym * src,Elf_External_Versym * dst)1865796c8dcSSimon Schubert _bfd_elf_swap_versym_out (bfd *abfd,
1875796c8dcSSimon Schubert const Elf_Internal_Versym *src,
1885796c8dcSSimon Schubert Elf_External_Versym *dst)
1895796c8dcSSimon Schubert {
1905796c8dcSSimon Schubert H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
1915796c8dcSSimon Schubert }
1925796c8dcSSimon Schubert
1935796c8dcSSimon Schubert /* Standard ELF hash function. Do not change this function; you will
1945796c8dcSSimon Schubert cause invalid hash tables to be generated. */
1955796c8dcSSimon Schubert
1965796c8dcSSimon Schubert unsigned long
bfd_elf_hash(const char * namearg)1975796c8dcSSimon Schubert bfd_elf_hash (const char *namearg)
1985796c8dcSSimon Schubert {
1995796c8dcSSimon Schubert const unsigned char *name = (const unsigned char *) namearg;
2005796c8dcSSimon Schubert unsigned long h = 0;
2015796c8dcSSimon Schubert unsigned long g;
2025796c8dcSSimon Schubert int ch;
2035796c8dcSSimon Schubert
2045796c8dcSSimon Schubert while ((ch = *name++) != '\0')
2055796c8dcSSimon Schubert {
2065796c8dcSSimon Schubert h = (h << 4) + ch;
2075796c8dcSSimon Schubert if ((g = (h & 0xf0000000)) != 0)
2085796c8dcSSimon Schubert {
2095796c8dcSSimon Schubert h ^= g >> 24;
2105796c8dcSSimon Schubert /* The ELF ABI says `h &= ~g', but this is equivalent in
2115796c8dcSSimon Schubert this case and on some machines one insn instead of two. */
2125796c8dcSSimon Schubert h ^= g;
2135796c8dcSSimon Schubert }
2145796c8dcSSimon Schubert }
2155796c8dcSSimon Schubert return h & 0xffffffff;
2165796c8dcSSimon Schubert }
2175796c8dcSSimon Schubert
2185796c8dcSSimon Schubert /* DT_GNU_HASH hash function. Do not change this function; you will
2195796c8dcSSimon Schubert cause invalid hash tables to be generated. */
2205796c8dcSSimon Schubert
2215796c8dcSSimon Schubert unsigned long
bfd_elf_gnu_hash(const char * namearg)2225796c8dcSSimon Schubert bfd_elf_gnu_hash (const char *namearg)
2235796c8dcSSimon Schubert {
2245796c8dcSSimon Schubert const unsigned char *name = (const unsigned char *) namearg;
2255796c8dcSSimon Schubert unsigned long h = 5381;
2265796c8dcSSimon Schubert unsigned char ch;
2275796c8dcSSimon Schubert
2285796c8dcSSimon Schubert while ((ch = *name++) != '\0')
2295796c8dcSSimon Schubert h = (h << 5) + h + ch;
2305796c8dcSSimon Schubert return h & 0xffffffff;
2315796c8dcSSimon Schubert }
2325796c8dcSSimon Schubert
2335796c8dcSSimon Schubert /* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
2345796c8dcSSimon Schubert the object_id field of an elf_obj_tdata field set to OBJECT_ID. */
2355796c8dcSSimon Schubert bfd_boolean
bfd_elf_allocate_object(bfd * abfd,size_t object_size,enum elf_target_id object_id)2365796c8dcSSimon Schubert bfd_elf_allocate_object (bfd *abfd,
2375796c8dcSSimon Schubert size_t object_size,
238cf7f2e2dSJohn Marino enum elf_target_id object_id)
2395796c8dcSSimon Schubert {
2405796c8dcSSimon Schubert BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
2415796c8dcSSimon Schubert abfd->tdata.any = bfd_zalloc (abfd, object_size);
2425796c8dcSSimon Schubert if (abfd->tdata.any == NULL)
2435796c8dcSSimon Schubert return FALSE;
2445796c8dcSSimon Schubert
2455796c8dcSSimon Schubert elf_object_id (abfd) = object_id;
246*ef5ccd6cSJohn Marino if (abfd->direction != read_direction)
247*ef5ccd6cSJohn Marino {
248*ef5ccd6cSJohn Marino struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
249*ef5ccd6cSJohn Marino if (o == NULL)
250*ef5ccd6cSJohn Marino return FALSE;
251*ef5ccd6cSJohn Marino elf_tdata (abfd)->o = o;
2525796c8dcSSimon Schubert elf_program_header_size (abfd) = (bfd_size_type) -1;
253*ef5ccd6cSJohn Marino }
2545796c8dcSSimon Schubert return TRUE;
2555796c8dcSSimon Schubert }
2565796c8dcSSimon Schubert
2575796c8dcSSimon Schubert
2585796c8dcSSimon Schubert bfd_boolean
bfd_elf_make_object(bfd * abfd)259c50c785cSJohn Marino bfd_elf_make_object (bfd *abfd)
2605796c8dcSSimon Schubert {
261c50c785cSJohn Marino const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2625796c8dcSSimon Schubert return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
263c50c785cSJohn Marino bed->target_id);
2645796c8dcSSimon Schubert }
2655796c8dcSSimon Schubert
2665796c8dcSSimon Schubert bfd_boolean
bfd_elf_mkcorefile(bfd * abfd)2675796c8dcSSimon Schubert bfd_elf_mkcorefile (bfd *abfd)
2685796c8dcSSimon Schubert {
2695796c8dcSSimon Schubert /* I think this can be done just like an object file. */
270*ef5ccd6cSJohn Marino if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
271*ef5ccd6cSJohn Marino return FALSE;
272*ef5ccd6cSJohn Marino elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
273*ef5ccd6cSJohn Marino return elf_tdata (abfd)->core != NULL;
2745796c8dcSSimon Schubert }
2755796c8dcSSimon Schubert
2765796c8dcSSimon Schubert static char *
bfd_elf_get_str_section(bfd * abfd,unsigned int shindex)2775796c8dcSSimon Schubert bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
2785796c8dcSSimon Schubert {
2795796c8dcSSimon Schubert Elf_Internal_Shdr **i_shdrp;
2805796c8dcSSimon Schubert bfd_byte *shstrtab = NULL;
2815796c8dcSSimon Schubert file_ptr offset;
2825796c8dcSSimon Schubert bfd_size_type shstrtabsize;
2835796c8dcSSimon Schubert
2845796c8dcSSimon Schubert i_shdrp = elf_elfsections (abfd);
2855796c8dcSSimon Schubert if (i_shdrp == 0
2865796c8dcSSimon Schubert || shindex >= elf_numsections (abfd)
2875796c8dcSSimon Schubert || i_shdrp[shindex] == 0)
2885796c8dcSSimon Schubert return NULL;
2895796c8dcSSimon Schubert
2905796c8dcSSimon Schubert shstrtab = i_shdrp[shindex]->contents;
2915796c8dcSSimon Schubert if (shstrtab == NULL)
2925796c8dcSSimon Schubert {
2935796c8dcSSimon Schubert /* No cached one, attempt to read, and cache what we read. */
2945796c8dcSSimon Schubert offset = i_shdrp[shindex]->sh_offset;
2955796c8dcSSimon Schubert shstrtabsize = i_shdrp[shindex]->sh_size;
2965796c8dcSSimon Schubert
2975796c8dcSSimon Schubert /* Allocate and clear an extra byte at the end, to prevent crashes
2985796c8dcSSimon Schubert in case the string table is not terminated. */
2995796c8dcSSimon Schubert if (shstrtabsize + 1 <= 1
3005796c8dcSSimon Schubert || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL
3015796c8dcSSimon Schubert || bfd_seek (abfd, offset, SEEK_SET) != 0)
3025796c8dcSSimon Schubert shstrtab = NULL;
3035796c8dcSSimon Schubert else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
3045796c8dcSSimon Schubert {
3055796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call)
3065796c8dcSSimon Schubert bfd_set_error (bfd_error_file_truncated);
3075796c8dcSSimon Schubert shstrtab = NULL;
3085796c8dcSSimon Schubert /* Once we've failed to read it, make sure we don't keep
3095796c8dcSSimon Schubert trying. Otherwise, we'll keep allocating space for
3105796c8dcSSimon Schubert the string table over and over. */
3115796c8dcSSimon Schubert i_shdrp[shindex]->sh_size = 0;
3125796c8dcSSimon Schubert }
3135796c8dcSSimon Schubert else
3145796c8dcSSimon Schubert shstrtab[shstrtabsize] = '\0';
3155796c8dcSSimon Schubert i_shdrp[shindex]->contents = shstrtab;
3165796c8dcSSimon Schubert }
3175796c8dcSSimon Schubert return (char *) shstrtab;
3185796c8dcSSimon Schubert }
3195796c8dcSSimon Schubert
3205796c8dcSSimon Schubert char *
bfd_elf_string_from_elf_section(bfd * abfd,unsigned int shindex,unsigned int strindex)3215796c8dcSSimon Schubert bfd_elf_string_from_elf_section (bfd *abfd,
3225796c8dcSSimon Schubert unsigned int shindex,
3235796c8dcSSimon Schubert unsigned int strindex)
3245796c8dcSSimon Schubert {
3255796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
3265796c8dcSSimon Schubert
3275796c8dcSSimon Schubert if (strindex == 0)
3285796c8dcSSimon Schubert return "";
3295796c8dcSSimon Schubert
3305796c8dcSSimon Schubert if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd))
3315796c8dcSSimon Schubert return NULL;
3325796c8dcSSimon Schubert
3335796c8dcSSimon Schubert hdr = elf_elfsections (abfd)[shindex];
3345796c8dcSSimon Schubert
3355796c8dcSSimon Schubert if (hdr->contents == NULL
3365796c8dcSSimon Schubert && bfd_elf_get_str_section (abfd, shindex) == NULL)
3375796c8dcSSimon Schubert return NULL;
3385796c8dcSSimon Schubert
3395796c8dcSSimon Schubert if (strindex >= hdr->sh_size)
3405796c8dcSSimon Schubert {
3415796c8dcSSimon Schubert unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
3425796c8dcSSimon Schubert (*_bfd_error_handler)
3435796c8dcSSimon Schubert (_("%B: invalid string offset %u >= %lu for section `%s'"),
3445796c8dcSSimon Schubert abfd, strindex, (unsigned long) hdr->sh_size,
3455796c8dcSSimon Schubert (shindex == shstrndx && strindex == hdr->sh_name
3465796c8dcSSimon Schubert ? ".shstrtab"
3475796c8dcSSimon Schubert : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
3485796c8dcSSimon Schubert return NULL;
3495796c8dcSSimon Schubert }
3505796c8dcSSimon Schubert
3515796c8dcSSimon Schubert return ((char *) hdr->contents) + strindex;
3525796c8dcSSimon Schubert }
3535796c8dcSSimon Schubert
3545796c8dcSSimon Schubert /* Read and convert symbols to internal format.
3555796c8dcSSimon Schubert SYMCOUNT specifies the number of symbols to read, starting from
3565796c8dcSSimon Schubert symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
3575796c8dcSSimon Schubert are non-NULL, they are used to store the internal symbols, external
3585796c8dcSSimon Schubert symbols, and symbol section index extensions, respectively.
3595796c8dcSSimon Schubert Returns a pointer to the internal symbol buffer (malloced if necessary)
3605796c8dcSSimon Schubert or NULL if there were no symbols or some kind of problem. */
3615796c8dcSSimon Schubert
3625796c8dcSSimon Schubert Elf_Internal_Sym *
bfd_elf_get_elf_syms(bfd * ibfd,Elf_Internal_Shdr * symtab_hdr,size_t symcount,size_t symoffset,Elf_Internal_Sym * intsym_buf,void * extsym_buf,Elf_External_Sym_Shndx * extshndx_buf)3635796c8dcSSimon Schubert bfd_elf_get_elf_syms (bfd *ibfd,
3645796c8dcSSimon Schubert Elf_Internal_Shdr *symtab_hdr,
3655796c8dcSSimon Schubert size_t symcount,
3665796c8dcSSimon Schubert size_t symoffset,
3675796c8dcSSimon Schubert Elf_Internal_Sym *intsym_buf,
3685796c8dcSSimon Schubert void *extsym_buf,
3695796c8dcSSimon Schubert Elf_External_Sym_Shndx *extshndx_buf)
3705796c8dcSSimon Schubert {
3715796c8dcSSimon Schubert Elf_Internal_Shdr *shndx_hdr;
3725796c8dcSSimon Schubert void *alloc_ext;
3735796c8dcSSimon Schubert const bfd_byte *esym;
3745796c8dcSSimon Schubert Elf_External_Sym_Shndx *alloc_extshndx;
3755796c8dcSSimon Schubert Elf_External_Sym_Shndx *shndx;
3765796c8dcSSimon Schubert Elf_Internal_Sym *alloc_intsym;
3775796c8dcSSimon Schubert Elf_Internal_Sym *isym;
3785796c8dcSSimon Schubert Elf_Internal_Sym *isymend;
3795796c8dcSSimon Schubert const struct elf_backend_data *bed;
3805796c8dcSSimon Schubert size_t extsym_size;
3815796c8dcSSimon Schubert bfd_size_type amt;
3825796c8dcSSimon Schubert file_ptr pos;
3835796c8dcSSimon Schubert
3845796c8dcSSimon Schubert if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
3855796c8dcSSimon Schubert abort ();
3865796c8dcSSimon Schubert
3875796c8dcSSimon Schubert if (symcount == 0)
3885796c8dcSSimon Schubert return intsym_buf;
3895796c8dcSSimon Schubert
3905796c8dcSSimon Schubert /* Normal syms might have section extension entries. */
3915796c8dcSSimon Schubert shndx_hdr = NULL;
3925796c8dcSSimon Schubert if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
3935796c8dcSSimon Schubert shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
3945796c8dcSSimon Schubert
3955796c8dcSSimon Schubert /* Read the symbols. */
3965796c8dcSSimon Schubert alloc_ext = NULL;
3975796c8dcSSimon Schubert alloc_extshndx = NULL;
3985796c8dcSSimon Schubert alloc_intsym = NULL;
3995796c8dcSSimon Schubert bed = get_elf_backend_data (ibfd);
4005796c8dcSSimon Schubert extsym_size = bed->s->sizeof_sym;
4015796c8dcSSimon Schubert amt = symcount * extsym_size;
4025796c8dcSSimon Schubert pos = symtab_hdr->sh_offset + symoffset * extsym_size;
4035796c8dcSSimon Schubert if (extsym_buf == NULL)
4045796c8dcSSimon Schubert {
4055796c8dcSSimon Schubert alloc_ext = bfd_malloc2 (symcount, extsym_size);
4065796c8dcSSimon Schubert extsym_buf = alloc_ext;
4075796c8dcSSimon Schubert }
4085796c8dcSSimon Schubert if (extsym_buf == NULL
4095796c8dcSSimon Schubert || bfd_seek (ibfd, pos, SEEK_SET) != 0
4105796c8dcSSimon Schubert || bfd_bread (extsym_buf, amt, ibfd) != amt)
4115796c8dcSSimon Schubert {
4125796c8dcSSimon Schubert intsym_buf = NULL;
4135796c8dcSSimon Schubert goto out;
4145796c8dcSSimon Schubert }
4155796c8dcSSimon Schubert
4165796c8dcSSimon Schubert if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
4175796c8dcSSimon Schubert extshndx_buf = NULL;
4185796c8dcSSimon Schubert else
4195796c8dcSSimon Schubert {
4205796c8dcSSimon Schubert amt = symcount * sizeof (Elf_External_Sym_Shndx);
4215796c8dcSSimon Schubert pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
4225796c8dcSSimon Schubert if (extshndx_buf == NULL)
4235796c8dcSSimon Schubert {
4245796c8dcSSimon Schubert alloc_extshndx = (Elf_External_Sym_Shndx *)
4255796c8dcSSimon Schubert bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx));
4265796c8dcSSimon Schubert extshndx_buf = alloc_extshndx;
4275796c8dcSSimon Schubert }
4285796c8dcSSimon Schubert if (extshndx_buf == NULL
4295796c8dcSSimon Schubert || bfd_seek (ibfd, pos, SEEK_SET) != 0
4305796c8dcSSimon Schubert || bfd_bread (extshndx_buf, amt, ibfd) != amt)
4315796c8dcSSimon Schubert {
4325796c8dcSSimon Schubert intsym_buf = NULL;
4335796c8dcSSimon Schubert goto out;
4345796c8dcSSimon Schubert }
4355796c8dcSSimon Schubert }
4365796c8dcSSimon Schubert
4375796c8dcSSimon Schubert if (intsym_buf == NULL)
4385796c8dcSSimon Schubert {
4395796c8dcSSimon Schubert alloc_intsym = (Elf_Internal_Sym *)
4405796c8dcSSimon Schubert bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
4415796c8dcSSimon Schubert intsym_buf = alloc_intsym;
4425796c8dcSSimon Schubert if (intsym_buf == NULL)
4435796c8dcSSimon Schubert goto out;
4445796c8dcSSimon Schubert }
4455796c8dcSSimon Schubert
4465796c8dcSSimon Schubert /* Convert the symbols to internal form. */
4475796c8dcSSimon Schubert isymend = intsym_buf + symcount;
4485796c8dcSSimon Schubert for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf,
4495796c8dcSSimon Schubert shndx = extshndx_buf;
4505796c8dcSSimon Schubert isym < isymend;
4515796c8dcSSimon Schubert esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
4525796c8dcSSimon Schubert if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
4535796c8dcSSimon Schubert {
4545796c8dcSSimon Schubert symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
4555796c8dcSSimon Schubert (*_bfd_error_handler) (_("%B symbol number %lu references "
4565796c8dcSSimon Schubert "nonexistent SHT_SYMTAB_SHNDX section"),
4575796c8dcSSimon Schubert ibfd, (unsigned long) symoffset);
4585796c8dcSSimon Schubert if (alloc_intsym != NULL)
4595796c8dcSSimon Schubert free (alloc_intsym);
4605796c8dcSSimon Schubert intsym_buf = NULL;
4615796c8dcSSimon Schubert goto out;
4625796c8dcSSimon Schubert }
4635796c8dcSSimon Schubert
4645796c8dcSSimon Schubert out:
4655796c8dcSSimon Schubert if (alloc_ext != NULL)
4665796c8dcSSimon Schubert free (alloc_ext);
4675796c8dcSSimon Schubert if (alloc_extshndx != NULL)
4685796c8dcSSimon Schubert free (alloc_extshndx);
4695796c8dcSSimon Schubert
4705796c8dcSSimon Schubert return intsym_buf;
4715796c8dcSSimon Schubert }
4725796c8dcSSimon Schubert
4735796c8dcSSimon Schubert /* Look up a symbol name. */
4745796c8dcSSimon Schubert const char *
bfd_elf_sym_name(bfd * abfd,Elf_Internal_Shdr * symtab_hdr,Elf_Internal_Sym * isym,asection * sym_sec)4755796c8dcSSimon Schubert bfd_elf_sym_name (bfd *abfd,
4765796c8dcSSimon Schubert Elf_Internal_Shdr *symtab_hdr,
4775796c8dcSSimon Schubert Elf_Internal_Sym *isym,
4785796c8dcSSimon Schubert asection *sym_sec)
4795796c8dcSSimon Schubert {
4805796c8dcSSimon Schubert const char *name;
4815796c8dcSSimon Schubert unsigned int iname = isym->st_name;
4825796c8dcSSimon Schubert unsigned int shindex = symtab_hdr->sh_link;
4835796c8dcSSimon Schubert
4845796c8dcSSimon Schubert if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
4855796c8dcSSimon Schubert /* Check for a bogus st_shndx to avoid crashing. */
4865796c8dcSSimon Schubert && isym->st_shndx < elf_numsections (abfd))
4875796c8dcSSimon Schubert {
4885796c8dcSSimon Schubert iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
4895796c8dcSSimon Schubert shindex = elf_elfheader (abfd)->e_shstrndx;
4905796c8dcSSimon Schubert }
4915796c8dcSSimon Schubert
4925796c8dcSSimon Schubert name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
4935796c8dcSSimon Schubert if (name == NULL)
4945796c8dcSSimon Schubert name = "(null)";
4955796c8dcSSimon Schubert else if (sym_sec && *name == '\0')
4965796c8dcSSimon Schubert name = bfd_section_name (abfd, sym_sec);
4975796c8dcSSimon Schubert
4985796c8dcSSimon Schubert return name;
4995796c8dcSSimon Schubert }
5005796c8dcSSimon Schubert
5015796c8dcSSimon Schubert /* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
5025796c8dcSSimon Schubert sections. The first element is the flags, the rest are section
5035796c8dcSSimon Schubert pointers. */
5045796c8dcSSimon Schubert
5055796c8dcSSimon Schubert typedef union elf_internal_group {
5065796c8dcSSimon Schubert Elf_Internal_Shdr *shdr;
5075796c8dcSSimon Schubert unsigned int flags;
5085796c8dcSSimon Schubert } Elf_Internal_Group;
5095796c8dcSSimon Schubert
5105796c8dcSSimon Schubert /* Return the name of the group signature symbol. Why isn't the
5115796c8dcSSimon Schubert signature just a string? */
5125796c8dcSSimon Schubert
5135796c8dcSSimon Schubert static const char *
group_signature(bfd * abfd,Elf_Internal_Shdr * ghdr)5145796c8dcSSimon Schubert group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
5155796c8dcSSimon Schubert {
5165796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
5175796c8dcSSimon Schubert unsigned char esym[sizeof (Elf64_External_Sym)];
5185796c8dcSSimon Schubert Elf_External_Sym_Shndx eshndx;
5195796c8dcSSimon Schubert Elf_Internal_Sym isym;
5205796c8dcSSimon Schubert
5215796c8dcSSimon Schubert /* First we need to ensure the symbol table is available. Make sure
5225796c8dcSSimon Schubert that it is a symbol table section. */
5235796c8dcSSimon Schubert if (ghdr->sh_link >= elf_numsections (abfd))
5245796c8dcSSimon Schubert return NULL;
5255796c8dcSSimon Schubert hdr = elf_elfsections (abfd) [ghdr->sh_link];
5265796c8dcSSimon Schubert if (hdr->sh_type != SHT_SYMTAB
5275796c8dcSSimon Schubert || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
5285796c8dcSSimon Schubert return NULL;
5295796c8dcSSimon Schubert
5305796c8dcSSimon Schubert /* Go read the symbol. */
5315796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->symtab_hdr;
5325796c8dcSSimon Schubert if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
5335796c8dcSSimon Schubert &isym, esym, &eshndx) == NULL)
5345796c8dcSSimon Schubert return NULL;
5355796c8dcSSimon Schubert
5365796c8dcSSimon Schubert return bfd_elf_sym_name (abfd, hdr, &isym, NULL);
5375796c8dcSSimon Schubert }
5385796c8dcSSimon Schubert
5395796c8dcSSimon Schubert /* Set next_in_group list pointer, and group name for NEWSECT. */
5405796c8dcSSimon Schubert
5415796c8dcSSimon Schubert static bfd_boolean
setup_group(bfd * abfd,Elf_Internal_Shdr * hdr,asection * newsect)5425796c8dcSSimon Schubert setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
5435796c8dcSSimon Schubert {
5445796c8dcSSimon Schubert unsigned int num_group = elf_tdata (abfd)->num_group;
5455796c8dcSSimon Schubert
5465796c8dcSSimon Schubert /* If num_group is zero, read in all SHT_GROUP sections. The count
5475796c8dcSSimon Schubert is set to -1 if there are no SHT_GROUP sections. */
5485796c8dcSSimon Schubert if (num_group == 0)
5495796c8dcSSimon Schubert {
5505796c8dcSSimon Schubert unsigned int i, shnum;
5515796c8dcSSimon Schubert
5525796c8dcSSimon Schubert /* First count the number of groups. If we have a SHT_GROUP
5535796c8dcSSimon Schubert section with just a flag word (ie. sh_size is 4), ignore it. */
5545796c8dcSSimon Schubert shnum = elf_numsections (abfd);
5555796c8dcSSimon Schubert num_group = 0;
5565796c8dcSSimon Schubert
557*ef5ccd6cSJohn Marino #define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize) \
5585796c8dcSSimon Schubert ( (shdr)->sh_type == SHT_GROUP \
559*ef5ccd6cSJohn Marino && (shdr)->sh_size >= minsize \
5605796c8dcSSimon Schubert && (shdr)->sh_entsize == GRP_ENTRY_SIZE \
5615796c8dcSSimon Schubert && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
5625796c8dcSSimon Schubert
5635796c8dcSSimon Schubert for (i = 0; i < shnum; i++)
5645796c8dcSSimon Schubert {
5655796c8dcSSimon Schubert Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
5665796c8dcSSimon Schubert
567*ef5ccd6cSJohn Marino if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
5685796c8dcSSimon Schubert num_group += 1;
5695796c8dcSSimon Schubert }
5705796c8dcSSimon Schubert
5715796c8dcSSimon Schubert if (num_group == 0)
5725796c8dcSSimon Schubert {
5735796c8dcSSimon Schubert num_group = (unsigned) -1;
5745796c8dcSSimon Schubert elf_tdata (abfd)->num_group = num_group;
5755796c8dcSSimon Schubert }
5765796c8dcSSimon Schubert else
5775796c8dcSSimon Schubert {
5785796c8dcSSimon Schubert /* We keep a list of elf section headers for group sections,
5795796c8dcSSimon Schubert so we can find them quickly. */
5805796c8dcSSimon Schubert bfd_size_type amt;
5815796c8dcSSimon Schubert
5825796c8dcSSimon Schubert elf_tdata (abfd)->num_group = num_group;
5835796c8dcSSimon Schubert elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **)
5845796c8dcSSimon Schubert bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
5855796c8dcSSimon Schubert if (elf_tdata (abfd)->group_sect_ptr == NULL)
5865796c8dcSSimon Schubert return FALSE;
5875796c8dcSSimon Schubert
5885796c8dcSSimon Schubert num_group = 0;
5895796c8dcSSimon Schubert for (i = 0; i < shnum; i++)
5905796c8dcSSimon Schubert {
5915796c8dcSSimon Schubert Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
5925796c8dcSSimon Schubert
593*ef5ccd6cSJohn Marino if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
5945796c8dcSSimon Schubert {
5955796c8dcSSimon Schubert unsigned char *src;
5965796c8dcSSimon Schubert Elf_Internal_Group *dest;
5975796c8dcSSimon Schubert
5985796c8dcSSimon Schubert /* Add to list of sections. */
5995796c8dcSSimon Schubert elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
6005796c8dcSSimon Schubert num_group += 1;
6015796c8dcSSimon Schubert
6025796c8dcSSimon Schubert /* Read the raw contents. */
6035796c8dcSSimon Schubert BFD_ASSERT (sizeof (*dest) >= 4);
6045796c8dcSSimon Schubert amt = shdr->sh_size * sizeof (*dest) / 4;
6055796c8dcSSimon Schubert shdr->contents = (unsigned char *)
6065796c8dcSSimon Schubert bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4);
6075796c8dcSSimon Schubert /* PR binutils/4110: Handle corrupt group headers. */
6085796c8dcSSimon Schubert if (shdr->contents == NULL)
6095796c8dcSSimon Schubert {
6105796c8dcSSimon Schubert _bfd_error_handler
6115796c8dcSSimon Schubert (_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
6125796c8dcSSimon Schubert bfd_set_error (bfd_error_bad_value);
6135796c8dcSSimon Schubert return FALSE;
6145796c8dcSSimon Schubert }
6155796c8dcSSimon Schubert
6165796c8dcSSimon Schubert memset (shdr->contents, 0, amt);
6175796c8dcSSimon Schubert
6185796c8dcSSimon Schubert if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
6195796c8dcSSimon Schubert || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
6205796c8dcSSimon Schubert != shdr->sh_size))
6215796c8dcSSimon Schubert return FALSE;
6225796c8dcSSimon Schubert
6235796c8dcSSimon Schubert /* Translate raw contents, a flag word followed by an
6245796c8dcSSimon Schubert array of elf section indices all in target byte order,
6255796c8dcSSimon Schubert to the flag word followed by an array of elf section
6265796c8dcSSimon Schubert pointers. */
6275796c8dcSSimon Schubert src = shdr->contents + shdr->sh_size;
6285796c8dcSSimon Schubert dest = (Elf_Internal_Group *) (shdr->contents + amt);
6295796c8dcSSimon Schubert while (1)
6305796c8dcSSimon Schubert {
6315796c8dcSSimon Schubert unsigned int idx;
6325796c8dcSSimon Schubert
6335796c8dcSSimon Schubert src -= 4;
6345796c8dcSSimon Schubert --dest;
6355796c8dcSSimon Schubert idx = H_GET_32 (abfd, src);
6365796c8dcSSimon Schubert if (src == shdr->contents)
6375796c8dcSSimon Schubert {
6385796c8dcSSimon Schubert dest->flags = idx;
6395796c8dcSSimon Schubert if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
6405796c8dcSSimon Schubert shdr->bfd_section->flags
6415796c8dcSSimon Schubert |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
6425796c8dcSSimon Schubert break;
6435796c8dcSSimon Schubert }
6445796c8dcSSimon Schubert if (idx >= shnum)
6455796c8dcSSimon Schubert {
6465796c8dcSSimon Schubert ((*_bfd_error_handler)
6475796c8dcSSimon Schubert (_("%B: invalid SHT_GROUP entry"), abfd));
6485796c8dcSSimon Schubert idx = 0;
6495796c8dcSSimon Schubert }
6505796c8dcSSimon Schubert dest->shdr = elf_elfsections (abfd)[idx];
6515796c8dcSSimon Schubert }
6525796c8dcSSimon Schubert }
6535796c8dcSSimon Schubert }
6545796c8dcSSimon Schubert }
6555796c8dcSSimon Schubert }
6565796c8dcSSimon Schubert
6575796c8dcSSimon Schubert if (num_group != (unsigned) -1)
6585796c8dcSSimon Schubert {
6595796c8dcSSimon Schubert unsigned int i;
6605796c8dcSSimon Schubert
6615796c8dcSSimon Schubert for (i = 0; i < num_group; i++)
6625796c8dcSSimon Schubert {
6635796c8dcSSimon Schubert Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
6645796c8dcSSimon Schubert Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
6655796c8dcSSimon Schubert unsigned int n_elt = shdr->sh_size / 4;
6665796c8dcSSimon Schubert
6675796c8dcSSimon Schubert /* Look through this group's sections to see if current
6685796c8dcSSimon Schubert section is a member. */
6695796c8dcSSimon Schubert while (--n_elt != 0)
6705796c8dcSSimon Schubert if ((++idx)->shdr == hdr)
6715796c8dcSSimon Schubert {
6725796c8dcSSimon Schubert asection *s = NULL;
6735796c8dcSSimon Schubert
6745796c8dcSSimon Schubert /* We are a member of this group. Go looking through
6755796c8dcSSimon Schubert other members to see if any others are linked via
6765796c8dcSSimon Schubert next_in_group. */
6775796c8dcSSimon Schubert idx = (Elf_Internal_Group *) shdr->contents;
6785796c8dcSSimon Schubert n_elt = shdr->sh_size / 4;
6795796c8dcSSimon Schubert while (--n_elt != 0)
6805796c8dcSSimon Schubert if ((s = (++idx)->shdr->bfd_section) != NULL
6815796c8dcSSimon Schubert && elf_next_in_group (s) != NULL)
6825796c8dcSSimon Schubert break;
6835796c8dcSSimon Schubert if (n_elt != 0)
6845796c8dcSSimon Schubert {
6855796c8dcSSimon Schubert /* Snarf the group name from other member, and
6865796c8dcSSimon Schubert insert current section in circular list. */
6875796c8dcSSimon Schubert elf_group_name (newsect) = elf_group_name (s);
6885796c8dcSSimon Schubert elf_next_in_group (newsect) = elf_next_in_group (s);
6895796c8dcSSimon Schubert elf_next_in_group (s) = newsect;
6905796c8dcSSimon Schubert }
6915796c8dcSSimon Schubert else
6925796c8dcSSimon Schubert {
6935796c8dcSSimon Schubert const char *gname;
6945796c8dcSSimon Schubert
6955796c8dcSSimon Schubert gname = group_signature (abfd, shdr);
6965796c8dcSSimon Schubert if (gname == NULL)
6975796c8dcSSimon Schubert return FALSE;
6985796c8dcSSimon Schubert elf_group_name (newsect) = gname;
6995796c8dcSSimon Schubert
7005796c8dcSSimon Schubert /* Start a circular list with one element. */
7015796c8dcSSimon Schubert elf_next_in_group (newsect) = newsect;
7025796c8dcSSimon Schubert }
7035796c8dcSSimon Schubert
7045796c8dcSSimon Schubert /* If the group section has been created, point to the
7055796c8dcSSimon Schubert new member. */
7065796c8dcSSimon Schubert if (shdr->bfd_section != NULL)
7075796c8dcSSimon Schubert elf_next_in_group (shdr->bfd_section) = newsect;
7085796c8dcSSimon Schubert
7095796c8dcSSimon Schubert i = num_group - 1;
7105796c8dcSSimon Schubert break;
7115796c8dcSSimon Schubert }
7125796c8dcSSimon Schubert }
7135796c8dcSSimon Schubert }
7145796c8dcSSimon Schubert
7155796c8dcSSimon Schubert if (elf_group_name (newsect) == NULL)
7165796c8dcSSimon Schubert {
7175796c8dcSSimon Schubert (*_bfd_error_handler) (_("%B: no group info for section %A"),
7185796c8dcSSimon Schubert abfd, newsect);
7195796c8dcSSimon Schubert }
7205796c8dcSSimon Schubert return TRUE;
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert
7235796c8dcSSimon Schubert bfd_boolean
_bfd_elf_setup_sections(bfd * abfd)7245796c8dcSSimon Schubert _bfd_elf_setup_sections (bfd *abfd)
7255796c8dcSSimon Schubert {
7265796c8dcSSimon Schubert unsigned int i;
7275796c8dcSSimon Schubert unsigned int num_group = elf_tdata (abfd)->num_group;
7285796c8dcSSimon Schubert bfd_boolean result = TRUE;
7295796c8dcSSimon Schubert asection *s;
7305796c8dcSSimon Schubert
7315796c8dcSSimon Schubert /* Process SHF_LINK_ORDER. */
7325796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
7335796c8dcSSimon Schubert {
7345796c8dcSSimon Schubert Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
7355796c8dcSSimon Schubert if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
7365796c8dcSSimon Schubert {
7375796c8dcSSimon Schubert unsigned int elfsec = this_hdr->sh_link;
7385796c8dcSSimon Schubert /* FIXME: The old Intel compiler and old strip/objcopy may
7395796c8dcSSimon Schubert not set the sh_link or sh_info fields. Hence we could
7405796c8dcSSimon Schubert get the situation where elfsec is 0. */
7415796c8dcSSimon Schubert if (elfsec == 0)
7425796c8dcSSimon Schubert {
7435796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7445796c8dcSSimon Schubert if (bed->link_order_error_handler)
7455796c8dcSSimon Schubert bed->link_order_error_handler
7465796c8dcSSimon Schubert (_("%B: warning: sh_link not set for section `%A'"),
7475796c8dcSSimon Schubert abfd, s);
7485796c8dcSSimon Schubert }
7495796c8dcSSimon Schubert else
7505796c8dcSSimon Schubert {
751cf7f2e2dSJohn Marino asection *linksec = NULL;
7525796c8dcSSimon Schubert
7535796c8dcSSimon Schubert if (elfsec < elf_numsections (abfd))
7545796c8dcSSimon Schubert {
7555796c8dcSSimon Schubert this_hdr = elf_elfsections (abfd)[elfsec];
756cf7f2e2dSJohn Marino linksec = this_hdr->bfd_section;
7575796c8dcSSimon Schubert }
7585796c8dcSSimon Schubert
7595796c8dcSSimon Schubert /* PR 1991, 2008:
7605796c8dcSSimon Schubert Some strip/objcopy may leave an incorrect value in
7615796c8dcSSimon Schubert sh_link. We don't want to proceed. */
762cf7f2e2dSJohn Marino if (linksec == NULL)
7635796c8dcSSimon Schubert {
7645796c8dcSSimon Schubert (*_bfd_error_handler)
7655796c8dcSSimon Schubert (_("%B: sh_link [%d] in section `%A' is incorrect"),
7665796c8dcSSimon Schubert s->owner, s, elfsec);
7675796c8dcSSimon Schubert result = FALSE;
7685796c8dcSSimon Schubert }
7695796c8dcSSimon Schubert
770cf7f2e2dSJohn Marino elf_linked_to_section (s) = linksec;
7715796c8dcSSimon Schubert }
7725796c8dcSSimon Schubert }
7735796c8dcSSimon Schubert }
7745796c8dcSSimon Schubert
7755796c8dcSSimon Schubert /* Process section groups. */
7765796c8dcSSimon Schubert if (num_group == (unsigned) -1)
7775796c8dcSSimon Schubert return result;
7785796c8dcSSimon Schubert
7795796c8dcSSimon Schubert for (i = 0; i < num_group; i++)
7805796c8dcSSimon Schubert {
7815796c8dcSSimon Schubert Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
7825796c8dcSSimon Schubert Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
7835796c8dcSSimon Schubert unsigned int n_elt = shdr->sh_size / 4;
7845796c8dcSSimon Schubert
7855796c8dcSSimon Schubert while (--n_elt != 0)
7865796c8dcSSimon Schubert if ((++idx)->shdr->bfd_section)
7875796c8dcSSimon Schubert elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
7885796c8dcSSimon Schubert else if (idx->shdr->sh_type == SHT_RELA
7895796c8dcSSimon Schubert || idx->shdr->sh_type == SHT_REL)
7905796c8dcSSimon Schubert /* We won't include relocation sections in section groups in
7915796c8dcSSimon Schubert output object files. We adjust the group section size here
7925796c8dcSSimon Schubert so that relocatable link will work correctly when
7935796c8dcSSimon Schubert relocation sections are in section group in input object
7945796c8dcSSimon Schubert files. */
7955796c8dcSSimon Schubert shdr->bfd_section->size -= 4;
7965796c8dcSSimon Schubert else
7975796c8dcSSimon Schubert {
7985796c8dcSSimon Schubert /* There are some unknown sections in the group. */
7995796c8dcSSimon Schubert (*_bfd_error_handler)
8005796c8dcSSimon Schubert (_("%B: unknown [%d] section `%s' in group [%s]"),
8015796c8dcSSimon Schubert abfd,
8025796c8dcSSimon Schubert (unsigned int) idx->shdr->sh_type,
8035796c8dcSSimon Schubert bfd_elf_string_from_elf_section (abfd,
8045796c8dcSSimon Schubert (elf_elfheader (abfd)
8055796c8dcSSimon Schubert ->e_shstrndx),
8065796c8dcSSimon Schubert idx->shdr->sh_name),
8075796c8dcSSimon Schubert shdr->bfd_section->name);
8085796c8dcSSimon Schubert result = FALSE;
8095796c8dcSSimon Schubert }
8105796c8dcSSimon Schubert }
8115796c8dcSSimon Schubert return result;
8125796c8dcSSimon Schubert }
8135796c8dcSSimon Schubert
8145796c8dcSSimon Schubert bfd_boolean
bfd_elf_is_group_section(bfd * abfd ATTRIBUTE_UNUSED,const asection * sec)8155796c8dcSSimon Schubert bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
8165796c8dcSSimon Schubert {
8175796c8dcSSimon Schubert return elf_next_in_group (sec) != NULL;
8185796c8dcSSimon Schubert }
8195796c8dcSSimon Schubert
8205796c8dcSSimon Schubert /* Make a BFD section from an ELF section. We store a pointer to the
8215796c8dcSSimon Schubert BFD section in the bfd_section field of the header. */
8225796c8dcSSimon Schubert
8235796c8dcSSimon Schubert bfd_boolean
_bfd_elf_make_section_from_shdr(bfd * abfd,Elf_Internal_Shdr * hdr,const char * name,int shindex)8245796c8dcSSimon Schubert _bfd_elf_make_section_from_shdr (bfd *abfd,
8255796c8dcSSimon Schubert Elf_Internal_Shdr *hdr,
8265796c8dcSSimon Schubert const char *name,
8275796c8dcSSimon Schubert int shindex)
8285796c8dcSSimon Schubert {
8295796c8dcSSimon Schubert asection *newsect;
8305796c8dcSSimon Schubert flagword flags;
8315796c8dcSSimon Schubert const struct elf_backend_data *bed;
8325796c8dcSSimon Schubert
8335796c8dcSSimon Schubert if (hdr->bfd_section != NULL)
8345796c8dcSSimon Schubert return TRUE;
8355796c8dcSSimon Schubert
8365796c8dcSSimon Schubert newsect = bfd_make_section_anyway (abfd, name);
8375796c8dcSSimon Schubert if (newsect == NULL)
8385796c8dcSSimon Schubert return FALSE;
8395796c8dcSSimon Schubert
8405796c8dcSSimon Schubert hdr->bfd_section = newsect;
8415796c8dcSSimon Schubert elf_section_data (newsect)->this_hdr = *hdr;
8425796c8dcSSimon Schubert elf_section_data (newsect)->this_idx = shindex;
8435796c8dcSSimon Schubert
8445796c8dcSSimon Schubert /* Always use the real type/flags. */
8455796c8dcSSimon Schubert elf_section_type (newsect) = hdr->sh_type;
8465796c8dcSSimon Schubert elf_section_flags (newsect) = hdr->sh_flags;
8475796c8dcSSimon Schubert
8485796c8dcSSimon Schubert newsect->filepos = hdr->sh_offset;
8495796c8dcSSimon Schubert
8505796c8dcSSimon Schubert if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
8515796c8dcSSimon Schubert || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
8525796c8dcSSimon Schubert || ! bfd_set_section_alignment (abfd, newsect,
8535796c8dcSSimon Schubert bfd_log2 (hdr->sh_addralign)))
8545796c8dcSSimon Schubert return FALSE;
8555796c8dcSSimon Schubert
8565796c8dcSSimon Schubert flags = SEC_NO_FLAGS;
8575796c8dcSSimon Schubert if (hdr->sh_type != SHT_NOBITS)
8585796c8dcSSimon Schubert flags |= SEC_HAS_CONTENTS;
8595796c8dcSSimon Schubert if (hdr->sh_type == SHT_GROUP)
8605796c8dcSSimon Schubert flags |= SEC_GROUP | SEC_EXCLUDE;
8615796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_ALLOC) != 0)
8625796c8dcSSimon Schubert {
8635796c8dcSSimon Schubert flags |= SEC_ALLOC;
8645796c8dcSSimon Schubert if (hdr->sh_type != SHT_NOBITS)
8655796c8dcSSimon Schubert flags |= SEC_LOAD;
8665796c8dcSSimon Schubert }
8675796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_WRITE) == 0)
8685796c8dcSSimon Schubert flags |= SEC_READONLY;
8695796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
8705796c8dcSSimon Schubert flags |= SEC_CODE;
8715796c8dcSSimon Schubert else if ((flags & SEC_LOAD) != 0)
8725796c8dcSSimon Schubert flags |= SEC_DATA;
8735796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_MERGE) != 0)
8745796c8dcSSimon Schubert {
8755796c8dcSSimon Schubert flags |= SEC_MERGE;
8765796c8dcSSimon Schubert newsect->entsize = hdr->sh_entsize;
8775796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_STRINGS) != 0)
8785796c8dcSSimon Schubert flags |= SEC_STRINGS;
8795796c8dcSSimon Schubert }
8805796c8dcSSimon Schubert if (hdr->sh_flags & SHF_GROUP)
8815796c8dcSSimon Schubert if (!setup_group (abfd, hdr, newsect))
8825796c8dcSSimon Schubert return FALSE;
8835796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_TLS) != 0)
8845796c8dcSSimon Schubert flags |= SEC_THREAD_LOCAL;
885cf7f2e2dSJohn Marino if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
886cf7f2e2dSJohn Marino flags |= SEC_EXCLUDE;
8875796c8dcSSimon Schubert
8885796c8dcSSimon Schubert if ((flags & SEC_ALLOC) == 0)
8895796c8dcSSimon Schubert {
8905796c8dcSSimon Schubert /* The debugging sections appear to be recognized only by name,
8915796c8dcSSimon Schubert not any sort of flag. Their SEC_ALLOC bits are cleared. */
8925796c8dcSSimon Schubert if (name [0] == '.')
8935796c8dcSSimon Schubert {
894*ef5ccd6cSJohn Marino const char *p;
895*ef5ccd6cSJohn Marino int n;
896*ef5ccd6cSJohn Marino if (name[1] == 'd')
897*ef5ccd6cSJohn Marino p = ".debug", n = 6;
898*ef5ccd6cSJohn Marino else if (name[1] == 'g' && name[2] == 'n')
899*ef5ccd6cSJohn Marino p = ".gnu.linkonce.wi.", n = 17;
900*ef5ccd6cSJohn Marino else if (name[1] == 'g' && name[2] == 'd')
901*ef5ccd6cSJohn Marino p = ".gdb_index", n = 11; /* yes we really do mean 11. */
902*ef5ccd6cSJohn Marino else if (name[1] == 'l')
903*ef5ccd6cSJohn Marino p = ".line", n = 5;
904*ef5ccd6cSJohn Marino else if (name[1] == 's')
905*ef5ccd6cSJohn Marino p = ".stab", n = 5;
906*ef5ccd6cSJohn Marino else if (name[1] == 'z')
907*ef5ccd6cSJohn Marino p = ".zdebug", n = 7;
908*ef5ccd6cSJohn Marino else
909*ef5ccd6cSJohn Marino p = NULL, n = 0;
910*ef5ccd6cSJohn Marino if (p != NULL && strncmp (name, p, n) == 0)
9115796c8dcSSimon Schubert flags |= SEC_DEBUGGING;
9125796c8dcSSimon Schubert }
9135796c8dcSSimon Schubert }
9145796c8dcSSimon Schubert
9155796c8dcSSimon Schubert /* As a GNU extension, if the name begins with .gnu.linkonce, we
9165796c8dcSSimon Schubert only link a single copy of the section. This is used to support
9175796c8dcSSimon Schubert g++. g++ will emit each template expansion in its own section.
9185796c8dcSSimon Schubert The symbols will be defined as weak, so that multiple definitions
9195796c8dcSSimon Schubert are permitted. The GNU linker extension is to actually discard
9205796c8dcSSimon Schubert all but one of the sections. */
9215796c8dcSSimon Schubert if (CONST_STRNEQ (name, ".gnu.linkonce")
9225796c8dcSSimon Schubert && elf_next_in_group (newsect) == NULL)
9235796c8dcSSimon Schubert flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
9245796c8dcSSimon Schubert
9255796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
9265796c8dcSSimon Schubert if (bed->elf_backend_section_flags)
9275796c8dcSSimon Schubert if (! bed->elf_backend_section_flags (&flags, hdr))
9285796c8dcSSimon Schubert return FALSE;
9295796c8dcSSimon Schubert
9305796c8dcSSimon Schubert if (! bfd_set_section_flags (abfd, newsect, flags))
9315796c8dcSSimon Schubert return FALSE;
9325796c8dcSSimon Schubert
9335796c8dcSSimon Schubert /* We do not parse the PT_NOTE segments as we are interested even in the
9345796c8dcSSimon Schubert separate debug info files which may have the segments offsets corrupted.
9355796c8dcSSimon Schubert PT_NOTEs from the core files are currently not parsed using BFD. */
9365796c8dcSSimon Schubert if (hdr->sh_type == SHT_NOTE)
9375796c8dcSSimon Schubert {
9385796c8dcSSimon Schubert bfd_byte *contents;
9395796c8dcSSimon Schubert
9405796c8dcSSimon Schubert if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
9415796c8dcSSimon Schubert return FALSE;
9425796c8dcSSimon Schubert
9435796c8dcSSimon Schubert elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);
9445796c8dcSSimon Schubert free (contents);
9455796c8dcSSimon Schubert }
9465796c8dcSSimon Schubert
9475796c8dcSSimon Schubert if ((flags & SEC_ALLOC) != 0)
9485796c8dcSSimon Schubert {
9495796c8dcSSimon Schubert Elf_Internal_Phdr *phdr;
9505796c8dcSSimon Schubert unsigned int i, nload;
9515796c8dcSSimon Schubert
9525796c8dcSSimon Schubert /* Some ELF linkers produce binaries with all the program header
9535796c8dcSSimon Schubert p_paddr fields zero. If we have such a binary with more than
9545796c8dcSSimon Schubert one PT_LOAD header, then leave the section lma equal to vma
9555796c8dcSSimon Schubert so that we don't create sections with overlapping lma. */
9565796c8dcSSimon Schubert phdr = elf_tdata (abfd)->phdr;
9575796c8dcSSimon Schubert for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
9585796c8dcSSimon Schubert if (phdr->p_paddr != 0)
9595796c8dcSSimon Schubert break;
9605796c8dcSSimon Schubert else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
9615796c8dcSSimon Schubert ++nload;
9625796c8dcSSimon Schubert if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
9635796c8dcSSimon Schubert return TRUE;
9645796c8dcSSimon Schubert
9655796c8dcSSimon Schubert phdr = elf_tdata (abfd)->phdr;
9665796c8dcSSimon Schubert for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
9675796c8dcSSimon Schubert {
968a45ae5f8SJohn Marino if (((phdr->p_type == PT_LOAD
969a45ae5f8SJohn Marino && (hdr->sh_flags & SHF_TLS) == 0)
970a45ae5f8SJohn Marino || phdr->p_type == PT_TLS)
971cf7f2e2dSJohn Marino && ELF_SECTION_IN_SEGMENT (hdr, phdr))
9725796c8dcSSimon Schubert {
9735796c8dcSSimon Schubert if ((flags & SEC_LOAD) == 0)
9745796c8dcSSimon Schubert newsect->lma = (phdr->p_paddr
9755796c8dcSSimon Schubert + hdr->sh_addr - phdr->p_vaddr);
9765796c8dcSSimon Schubert else
9775796c8dcSSimon Schubert /* We used to use the same adjustment for SEC_LOAD
9785796c8dcSSimon Schubert sections, but that doesn't work if the segment
9795796c8dcSSimon Schubert is packed with code from multiple VMAs.
9805796c8dcSSimon Schubert Instead we calculate the section LMA based on
9815796c8dcSSimon Schubert the segment LMA. It is assumed that the
9825796c8dcSSimon Schubert segment will contain sections with contiguous
9835796c8dcSSimon Schubert LMAs, even if the VMAs are not. */
9845796c8dcSSimon Schubert newsect->lma = (phdr->p_paddr
9855796c8dcSSimon Schubert + hdr->sh_offset - phdr->p_offset);
9865796c8dcSSimon Schubert
9875796c8dcSSimon Schubert /* With contiguous segments, we can't tell from file
9885796c8dcSSimon Schubert offsets whether a section with zero size should
9895796c8dcSSimon Schubert be placed at the end of one segment or the
9905796c8dcSSimon Schubert beginning of the next. Decide based on vaddr. */
9915796c8dcSSimon Schubert if (hdr->sh_addr >= phdr->p_vaddr
9925796c8dcSSimon Schubert && (hdr->sh_addr + hdr->sh_size
9935796c8dcSSimon Schubert <= phdr->p_vaddr + phdr->p_memsz))
9945796c8dcSSimon Schubert break;
9955796c8dcSSimon Schubert }
9965796c8dcSSimon Schubert }
9975796c8dcSSimon Schubert }
9985796c8dcSSimon Schubert
999c50c785cSJohn Marino /* Compress/decompress DWARF debug sections with names: .debug_* and
1000c50c785cSJohn Marino .zdebug_*, after the section flags is set. */
1001c50c785cSJohn Marino if ((flags & SEC_DEBUGGING)
1002c50c785cSJohn Marino && ((name[1] == 'd' && name[6] == '_')
1003c50c785cSJohn Marino || (name[1] == 'z' && name[7] == '_')))
1004c50c785cSJohn Marino {
1005c50c785cSJohn Marino enum { nothing, compress, decompress } action = nothing;
1006c50c785cSJohn Marino char *new_name;
1007c50c785cSJohn Marino
1008c50c785cSJohn Marino if (bfd_is_section_compressed (abfd, newsect))
1009c50c785cSJohn Marino {
1010c50c785cSJohn Marino /* Compressed section. Check if we should decompress. */
1011c50c785cSJohn Marino if ((abfd->flags & BFD_DECOMPRESS))
1012c50c785cSJohn Marino action = decompress;
1013c50c785cSJohn Marino }
1014c50c785cSJohn Marino else
1015c50c785cSJohn Marino {
1016c50c785cSJohn Marino /* Normal section. Check if we should compress. */
1017*ef5ccd6cSJohn Marino if ((abfd->flags & BFD_COMPRESS) && newsect->size != 0)
1018c50c785cSJohn Marino action = compress;
1019c50c785cSJohn Marino }
1020c50c785cSJohn Marino
1021c50c785cSJohn Marino new_name = NULL;
1022c50c785cSJohn Marino switch (action)
1023c50c785cSJohn Marino {
1024c50c785cSJohn Marino case nothing:
1025c50c785cSJohn Marino break;
1026c50c785cSJohn Marino case compress:
1027c50c785cSJohn Marino if (!bfd_init_section_compress_status (abfd, newsect))
1028c50c785cSJohn Marino {
1029c50c785cSJohn Marino (*_bfd_error_handler)
1030*ef5ccd6cSJohn Marino (_("%B: unable to initialize compress status for section %s"),
1031c50c785cSJohn Marino abfd, name);
1032c50c785cSJohn Marino return FALSE;
1033c50c785cSJohn Marino }
1034c50c785cSJohn Marino if (name[1] != 'z')
1035c50c785cSJohn Marino {
1036c50c785cSJohn Marino unsigned int len = strlen (name);
1037c50c785cSJohn Marino
1038c50c785cSJohn Marino new_name = bfd_alloc (abfd, len + 2);
1039c50c785cSJohn Marino if (new_name == NULL)
1040c50c785cSJohn Marino return FALSE;
1041c50c785cSJohn Marino new_name[0] = '.';
1042c50c785cSJohn Marino new_name[1] = 'z';
1043c50c785cSJohn Marino memcpy (new_name + 2, name + 1, len);
1044c50c785cSJohn Marino }
1045c50c785cSJohn Marino break;
1046c50c785cSJohn Marino case decompress:
1047c50c785cSJohn Marino if (!bfd_init_section_decompress_status (abfd, newsect))
1048c50c785cSJohn Marino {
1049c50c785cSJohn Marino (*_bfd_error_handler)
1050*ef5ccd6cSJohn Marino (_("%B: unable to initialize decompress status for section %s"),
1051c50c785cSJohn Marino abfd, name);
1052c50c785cSJohn Marino return FALSE;
1053c50c785cSJohn Marino }
1054c50c785cSJohn Marino if (name[1] == 'z')
1055c50c785cSJohn Marino {
1056c50c785cSJohn Marino unsigned int len = strlen (name);
1057c50c785cSJohn Marino
1058c50c785cSJohn Marino new_name = bfd_alloc (abfd, len);
1059c50c785cSJohn Marino if (new_name == NULL)
1060c50c785cSJohn Marino return FALSE;
1061c50c785cSJohn Marino new_name[0] = '.';
1062c50c785cSJohn Marino memcpy (new_name + 1, name + 2, len - 1);
1063c50c785cSJohn Marino }
1064c50c785cSJohn Marino break;
1065c50c785cSJohn Marino }
1066c50c785cSJohn Marino if (new_name != NULL)
1067c50c785cSJohn Marino bfd_rename_section (abfd, newsect, new_name);
1068c50c785cSJohn Marino }
1069c50c785cSJohn Marino
10705796c8dcSSimon Schubert return TRUE;
10715796c8dcSSimon Schubert }
10725796c8dcSSimon Schubert
10735796c8dcSSimon Schubert const char *const bfd_elf_section_type_names[] = {
10745796c8dcSSimon Schubert "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
10755796c8dcSSimon Schubert "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
10765796c8dcSSimon Schubert "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
10775796c8dcSSimon Schubert };
10785796c8dcSSimon Schubert
10795796c8dcSSimon Schubert /* ELF relocs are against symbols. If we are producing relocatable
10805796c8dcSSimon Schubert output, and the reloc is against an external symbol, and nothing
10815796c8dcSSimon Schubert has given us any additional addend, the resulting reloc will also
10825796c8dcSSimon Schubert be against the same symbol. In such a case, we don't want to
10835796c8dcSSimon Schubert change anything about the way the reloc is handled, since it will
10845796c8dcSSimon Schubert all be done at final link time. Rather than put special case code
10855796c8dcSSimon Schubert into bfd_perform_relocation, all the reloc types use this howto
10865796c8dcSSimon Schubert function. It just short circuits the reloc if producing
10875796c8dcSSimon Schubert relocatable output against an external symbol. */
10885796c8dcSSimon Schubert
10895796c8dcSSimon Schubert bfd_reloc_status_type
bfd_elf_generic_reloc(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol,void * data ATTRIBUTE_UNUSED,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)10905796c8dcSSimon Schubert bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
10915796c8dcSSimon Schubert arelent *reloc_entry,
10925796c8dcSSimon Schubert asymbol *symbol,
10935796c8dcSSimon Schubert void *data ATTRIBUTE_UNUSED,
10945796c8dcSSimon Schubert asection *input_section,
10955796c8dcSSimon Schubert bfd *output_bfd,
10965796c8dcSSimon Schubert char **error_message ATTRIBUTE_UNUSED)
10975796c8dcSSimon Schubert {
10985796c8dcSSimon Schubert if (output_bfd != NULL
10995796c8dcSSimon Schubert && (symbol->flags & BSF_SECTION_SYM) == 0
11005796c8dcSSimon Schubert && (! reloc_entry->howto->partial_inplace
11015796c8dcSSimon Schubert || reloc_entry->addend == 0))
11025796c8dcSSimon Schubert {
11035796c8dcSSimon Schubert reloc_entry->address += input_section->output_offset;
11045796c8dcSSimon Schubert return bfd_reloc_ok;
11055796c8dcSSimon Schubert }
11065796c8dcSSimon Schubert
11075796c8dcSSimon Schubert return bfd_reloc_continue;
11085796c8dcSSimon Schubert }
11095796c8dcSSimon Schubert
11105796c8dcSSimon Schubert /* Copy the program header and other data from one object module to
11115796c8dcSSimon Schubert another. */
11125796c8dcSSimon Schubert
11135796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_bfd_data(bfd * ibfd,bfd * obfd)11145796c8dcSSimon Schubert _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
11155796c8dcSSimon Schubert {
11165796c8dcSSimon Schubert if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
11175796c8dcSSimon Schubert || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
11185796c8dcSSimon Schubert return TRUE;
11195796c8dcSSimon Schubert
11205796c8dcSSimon Schubert BFD_ASSERT (!elf_flags_init (obfd)
11215796c8dcSSimon Schubert || (elf_elfheader (obfd)->e_flags
11225796c8dcSSimon Schubert == elf_elfheader (ibfd)->e_flags));
11235796c8dcSSimon Schubert
11245796c8dcSSimon Schubert elf_gp (obfd) = elf_gp (ibfd);
11255796c8dcSSimon Schubert elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
11265796c8dcSSimon Schubert elf_flags_init (obfd) = TRUE;
11275796c8dcSSimon Schubert
11285796c8dcSSimon Schubert /* Copy object attributes. */
11295796c8dcSSimon Schubert _bfd_elf_copy_obj_attributes (ibfd, obfd);
11305796c8dcSSimon Schubert return TRUE;
11315796c8dcSSimon Schubert }
11325796c8dcSSimon Schubert
11335796c8dcSSimon Schubert static const char *
get_segment_type(unsigned int p_type)11345796c8dcSSimon Schubert get_segment_type (unsigned int p_type)
11355796c8dcSSimon Schubert {
11365796c8dcSSimon Schubert const char *pt;
11375796c8dcSSimon Schubert switch (p_type)
11385796c8dcSSimon Schubert {
11395796c8dcSSimon Schubert case PT_NULL: pt = "NULL"; break;
11405796c8dcSSimon Schubert case PT_LOAD: pt = "LOAD"; break;
11415796c8dcSSimon Schubert case PT_DYNAMIC: pt = "DYNAMIC"; break;
11425796c8dcSSimon Schubert case PT_INTERP: pt = "INTERP"; break;
11435796c8dcSSimon Schubert case PT_NOTE: pt = "NOTE"; break;
11445796c8dcSSimon Schubert case PT_SHLIB: pt = "SHLIB"; break;
11455796c8dcSSimon Schubert case PT_PHDR: pt = "PHDR"; break;
11465796c8dcSSimon Schubert case PT_TLS: pt = "TLS"; break;
11475796c8dcSSimon Schubert case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
11485796c8dcSSimon Schubert case PT_GNU_STACK: pt = "STACK"; break;
11495796c8dcSSimon Schubert case PT_GNU_RELRO: pt = "RELRO"; break;
11505796c8dcSSimon Schubert default: pt = NULL; break;
11515796c8dcSSimon Schubert }
11525796c8dcSSimon Schubert return pt;
11535796c8dcSSimon Schubert }
11545796c8dcSSimon Schubert
11555796c8dcSSimon Schubert /* Print out the program headers. */
11565796c8dcSSimon Schubert
11575796c8dcSSimon Schubert bfd_boolean
_bfd_elf_print_private_bfd_data(bfd * abfd,void * farg)11585796c8dcSSimon Schubert _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
11595796c8dcSSimon Schubert {
11605796c8dcSSimon Schubert FILE *f = (FILE *) farg;
11615796c8dcSSimon Schubert Elf_Internal_Phdr *p;
11625796c8dcSSimon Schubert asection *s;
11635796c8dcSSimon Schubert bfd_byte *dynbuf = NULL;
11645796c8dcSSimon Schubert
11655796c8dcSSimon Schubert p = elf_tdata (abfd)->phdr;
11665796c8dcSSimon Schubert if (p != NULL)
11675796c8dcSSimon Schubert {
11685796c8dcSSimon Schubert unsigned int i, c;
11695796c8dcSSimon Schubert
11705796c8dcSSimon Schubert fprintf (f, _("\nProgram Header:\n"));
11715796c8dcSSimon Schubert c = elf_elfheader (abfd)->e_phnum;
11725796c8dcSSimon Schubert for (i = 0; i < c; i++, p++)
11735796c8dcSSimon Schubert {
11745796c8dcSSimon Schubert const char *pt = get_segment_type (p->p_type);
11755796c8dcSSimon Schubert char buf[20];
11765796c8dcSSimon Schubert
11775796c8dcSSimon Schubert if (pt == NULL)
11785796c8dcSSimon Schubert {
11795796c8dcSSimon Schubert sprintf (buf, "0x%lx", p->p_type);
11805796c8dcSSimon Schubert pt = buf;
11815796c8dcSSimon Schubert }
11825796c8dcSSimon Schubert fprintf (f, "%8s off 0x", pt);
11835796c8dcSSimon Schubert bfd_fprintf_vma (abfd, f, p->p_offset);
11845796c8dcSSimon Schubert fprintf (f, " vaddr 0x");
11855796c8dcSSimon Schubert bfd_fprintf_vma (abfd, f, p->p_vaddr);
11865796c8dcSSimon Schubert fprintf (f, " paddr 0x");
11875796c8dcSSimon Schubert bfd_fprintf_vma (abfd, f, p->p_paddr);
11885796c8dcSSimon Schubert fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
11895796c8dcSSimon Schubert fprintf (f, " filesz 0x");
11905796c8dcSSimon Schubert bfd_fprintf_vma (abfd, f, p->p_filesz);
11915796c8dcSSimon Schubert fprintf (f, " memsz 0x");
11925796c8dcSSimon Schubert bfd_fprintf_vma (abfd, f, p->p_memsz);
11935796c8dcSSimon Schubert fprintf (f, " flags %c%c%c",
11945796c8dcSSimon Schubert (p->p_flags & PF_R) != 0 ? 'r' : '-',
11955796c8dcSSimon Schubert (p->p_flags & PF_W) != 0 ? 'w' : '-',
11965796c8dcSSimon Schubert (p->p_flags & PF_X) != 0 ? 'x' : '-');
11975796c8dcSSimon Schubert if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
11985796c8dcSSimon Schubert fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
11995796c8dcSSimon Schubert fprintf (f, "\n");
12005796c8dcSSimon Schubert }
12015796c8dcSSimon Schubert }
12025796c8dcSSimon Schubert
12035796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, ".dynamic");
12045796c8dcSSimon Schubert if (s != NULL)
12055796c8dcSSimon Schubert {
12065796c8dcSSimon Schubert unsigned int elfsec;
12075796c8dcSSimon Schubert unsigned long shlink;
12085796c8dcSSimon Schubert bfd_byte *extdyn, *extdynend;
12095796c8dcSSimon Schubert size_t extdynsize;
12105796c8dcSSimon Schubert void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
12115796c8dcSSimon Schubert
12125796c8dcSSimon Schubert fprintf (f, _("\nDynamic Section:\n"));
12135796c8dcSSimon Schubert
12145796c8dcSSimon Schubert if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
12155796c8dcSSimon Schubert goto error_return;
12165796c8dcSSimon Schubert
12175796c8dcSSimon Schubert elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
12185796c8dcSSimon Schubert if (elfsec == SHN_BAD)
12195796c8dcSSimon Schubert goto error_return;
12205796c8dcSSimon Schubert shlink = elf_elfsections (abfd)[elfsec]->sh_link;
12215796c8dcSSimon Schubert
12225796c8dcSSimon Schubert extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
12235796c8dcSSimon Schubert swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
12245796c8dcSSimon Schubert
12255796c8dcSSimon Schubert extdyn = dynbuf;
12265796c8dcSSimon Schubert extdynend = extdyn + s->size;
12275796c8dcSSimon Schubert for (; extdyn < extdynend; extdyn += extdynsize)
12285796c8dcSSimon Schubert {
12295796c8dcSSimon Schubert Elf_Internal_Dyn dyn;
12305796c8dcSSimon Schubert const char *name = "";
12315796c8dcSSimon Schubert char ab[20];
12325796c8dcSSimon Schubert bfd_boolean stringp;
12335796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
12345796c8dcSSimon Schubert
12355796c8dcSSimon Schubert (*swap_dyn_in) (abfd, extdyn, &dyn);
12365796c8dcSSimon Schubert
12375796c8dcSSimon Schubert if (dyn.d_tag == DT_NULL)
12385796c8dcSSimon Schubert break;
12395796c8dcSSimon Schubert
12405796c8dcSSimon Schubert stringp = FALSE;
12415796c8dcSSimon Schubert switch (dyn.d_tag)
12425796c8dcSSimon Schubert {
12435796c8dcSSimon Schubert default:
12445796c8dcSSimon Schubert if (bed->elf_backend_get_target_dtag)
12455796c8dcSSimon Schubert name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
12465796c8dcSSimon Schubert
12475796c8dcSSimon Schubert if (!strcmp (name, ""))
12485796c8dcSSimon Schubert {
12495796c8dcSSimon Schubert sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
12505796c8dcSSimon Schubert name = ab;
12515796c8dcSSimon Schubert }
12525796c8dcSSimon Schubert break;
12535796c8dcSSimon Schubert
12545796c8dcSSimon Schubert case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
12555796c8dcSSimon Schubert case DT_PLTRELSZ: name = "PLTRELSZ"; break;
12565796c8dcSSimon Schubert case DT_PLTGOT: name = "PLTGOT"; break;
12575796c8dcSSimon Schubert case DT_HASH: name = "HASH"; break;
12585796c8dcSSimon Schubert case DT_STRTAB: name = "STRTAB"; break;
12595796c8dcSSimon Schubert case DT_SYMTAB: name = "SYMTAB"; break;
12605796c8dcSSimon Schubert case DT_RELA: name = "RELA"; break;
12615796c8dcSSimon Schubert case DT_RELASZ: name = "RELASZ"; break;
12625796c8dcSSimon Schubert case DT_RELAENT: name = "RELAENT"; break;
12635796c8dcSSimon Schubert case DT_STRSZ: name = "STRSZ"; break;
12645796c8dcSSimon Schubert case DT_SYMENT: name = "SYMENT"; break;
12655796c8dcSSimon Schubert case DT_INIT: name = "INIT"; break;
12665796c8dcSSimon Schubert case DT_FINI: name = "FINI"; break;
12675796c8dcSSimon Schubert case DT_SONAME: name = "SONAME"; stringp = TRUE; break;
12685796c8dcSSimon Schubert case DT_RPATH: name = "RPATH"; stringp = TRUE; break;
12695796c8dcSSimon Schubert case DT_SYMBOLIC: name = "SYMBOLIC"; break;
12705796c8dcSSimon Schubert case DT_REL: name = "REL"; break;
12715796c8dcSSimon Schubert case DT_RELSZ: name = "RELSZ"; break;
12725796c8dcSSimon Schubert case DT_RELENT: name = "RELENT"; break;
12735796c8dcSSimon Schubert case DT_PLTREL: name = "PLTREL"; break;
12745796c8dcSSimon Schubert case DT_DEBUG: name = "DEBUG"; break;
12755796c8dcSSimon Schubert case DT_TEXTREL: name = "TEXTREL"; break;
12765796c8dcSSimon Schubert case DT_JMPREL: name = "JMPREL"; break;
12775796c8dcSSimon Schubert case DT_BIND_NOW: name = "BIND_NOW"; break;
12785796c8dcSSimon Schubert case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
12795796c8dcSSimon Schubert case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
12805796c8dcSSimon Schubert case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
12815796c8dcSSimon Schubert case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
12825796c8dcSSimon Schubert case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break;
12835796c8dcSSimon Schubert case DT_FLAGS: name = "FLAGS"; break;
12845796c8dcSSimon Schubert case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
12855796c8dcSSimon Schubert case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
12865796c8dcSSimon Schubert case DT_CHECKSUM: name = "CHECKSUM"; break;
12875796c8dcSSimon Schubert case DT_PLTPADSZ: name = "PLTPADSZ"; break;
12885796c8dcSSimon Schubert case DT_MOVEENT: name = "MOVEENT"; break;
12895796c8dcSSimon Schubert case DT_MOVESZ: name = "MOVESZ"; break;
12905796c8dcSSimon Schubert case DT_FEATURE: name = "FEATURE"; break;
12915796c8dcSSimon Schubert case DT_POSFLAG_1: name = "POSFLAG_1"; break;
12925796c8dcSSimon Schubert case DT_SYMINSZ: name = "SYMINSZ"; break;
12935796c8dcSSimon Schubert case DT_SYMINENT: name = "SYMINENT"; break;
12945796c8dcSSimon Schubert case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break;
12955796c8dcSSimon Schubert case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break;
12965796c8dcSSimon Schubert case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break;
12975796c8dcSSimon Schubert case DT_PLTPAD: name = "PLTPAD"; break;
12985796c8dcSSimon Schubert case DT_MOVETAB: name = "MOVETAB"; break;
12995796c8dcSSimon Schubert case DT_SYMINFO: name = "SYMINFO"; break;
13005796c8dcSSimon Schubert case DT_RELACOUNT: name = "RELACOUNT"; break;
13015796c8dcSSimon Schubert case DT_RELCOUNT: name = "RELCOUNT"; break;
13025796c8dcSSimon Schubert case DT_FLAGS_1: name = "FLAGS_1"; break;
13035796c8dcSSimon Schubert case DT_VERSYM: name = "VERSYM"; break;
13045796c8dcSSimon Schubert case DT_VERDEF: name = "VERDEF"; break;
13055796c8dcSSimon Schubert case DT_VERDEFNUM: name = "VERDEFNUM"; break;
13065796c8dcSSimon Schubert case DT_VERNEED: name = "VERNEED"; break;
13075796c8dcSSimon Schubert case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
13085796c8dcSSimon Schubert case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
13095796c8dcSSimon Schubert case DT_USED: name = "USED"; break;
13105796c8dcSSimon Schubert case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
13115796c8dcSSimon Schubert case DT_GNU_HASH: name = "GNU_HASH"; break;
13125796c8dcSSimon Schubert }
13135796c8dcSSimon Schubert
13145796c8dcSSimon Schubert fprintf (f, " %-20s ", name);
13155796c8dcSSimon Schubert if (! stringp)
13165796c8dcSSimon Schubert {
13175796c8dcSSimon Schubert fprintf (f, "0x");
13185796c8dcSSimon Schubert bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
13195796c8dcSSimon Schubert }
13205796c8dcSSimon Schubert else
13215796c8dcSSimon Schubert {
13225796c8dcSSimon Schubert const char *string;
13235796c8dcSSimon Schubert unsigned int tagv = dyn.d_un.d_val;
13245796c8dcSSimon Schubert
13255796c8dcSSimon Schubert string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
13265796c8dcSSimon Schubert if (string == NULL)
13275796c8dcSSimon Schubert goto error_return;
13285796c8dcSSimon Schubert fprintf (f, "%s", string);
13295796c8dcSSimon Schubert }
13305796c8dcSSimon Schubert fprintf (f, "\n");
13315796c8dcSSimon Schubert }
13325796c8dcSSimon Schubert
13335796c8dcSSimon Schubert free (dynbuf);
13345796c8dcSSimon Schubert dynbuf = NULL;
13355796c8dcSSimon Schubert }
13365796c8dcSSimon Schubert
13375796c8dcSSimon Schubert if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
13385796c8dcSSimon Schubert || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
13395796c8dcSSimon Schubert {
13405796c8dcSSimon Schubert if (! _bfd_elf_slurp_version_tables (abfd, FALSE))
13415796c8dcSSimon Schubert return FALSE;
13425796c8dcSSimon Schubert }
13435796c8dcSSimon Schubert
13445796c8dcSSimon Schubert if (elf_dynverdef (abfd) != 0)
13455796c8dcSSimon Schubert {
13465796c8dcSSimon Schubert Elf_Internal_Verdef *t;
13475796c8dcSSimon Schubert
13485796c8dcSSimon Schubert fprintf (f, _("\nVersion definitions:\n"));
13495796c8dcSSimon Schubert for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
13505796c8dcSSimon Schubert {
13515796c8dcSSimon Schubert fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
13525796c8dcSSimon Schubert t->vd_flags, t->vd_hash,
13535796c8dcSSimon Schubert t->vd_nodename ? t->vd_nodename : "<corrupt>");
13545796c8dcSSimon Schubert if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
13555796c8dcSSimon Schubert {
13565796c8dcSSimon Schubert Elf_Internal_Verdaux *a;
13575796c8dcSSimon Schubert
13585796c8dcSSimon Schubert fprintf (f, "\t");
13595796c8dcSSimon Schubert for (a = t->vd_auxptr->vda_nextptr;
13605796c8dcSSimon Schubert a != NULL;
13615796c8dcSSimon Schubert a = a->vda_nextptr)
13625796c8dcSSimon Schubert fprintf (f, "%s ",
13635796c8dcSSimon Schubert a->vda_nodename ? a->vda_nodename : "<corrupt>");
13645796c8dcSSimon Schubert fprintf (f, "\n");
13655796c8dcSSimon Schubert }
13665796c8dcSSimon Schubert }
13675796c8dcSSimon Schubert }
13685796c8dcSSimon Schubert
13695796c8dcSSimon Schubert if (elf_dynverref (abfd) != 0)
13705796c8dcSSimon Schubert {
13715796c8dcSSimon Schubert Elf_Internal_Verneed *t;
13725796c8dcSSimon Schubert
13735796c8dcSSimon Schubert fprintf (f, _("\nVersion References:\n"));
13745796c8dcSSimon Schubert for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
13755796c8dcSSimon Schubert {
13765796c8dcSSimon Schubert Elf_Internal_Vernaux *a;
13775796c8dcSSimon Schubert
13785796c8dcSSimon Schubert fprintf (f, _(" required from %s:\n"),
13795796c8dcSSimon Schubert t->vn_filename ? t->vn_filename : "<corrupt>");
13805796c8dcSSimon Schubert for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
13815796c8dcSSimon Schubert fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
13825796c8dcSSimon Schubert a->vna_flags, a->vna_other,
13835796c8dcSSimon Schubert a->vna_nodename ? a->vna_nodename : "<corrupt>");
13845796c8dcSSimon Schubert }
13855796c8dcSSimon Schubert }
13865796c8dcSSimon Schubert
13875796c8dcSSimon Schubert return TRUE;
13885796c8dcSSimon Schubert
13895796c8dcSSimon Schubert error_return:
13905796c8dcSSimon Schubert if (dynbuf != NULL)
13915796c8dcSSimon Schubert free (dynbuf);
13925796c8dcSSimon Schubert return FALSE;
13935796c8dcSSimon Schubert }
13945796c8dcSSimon Schubert
13955796c8dcSSimon Schubert /* Display ELF-specific fields of a symbol. */
13965796c8dcSSimon Schubert
13975796c8dcSSimon Schubert void
bfd_elf_print_symbol(bfd * abfd,void * filep,asymbol * symbol,bfd_print_symbol_type how)13985796c8dcSSimon Schubert bfd_elf_print_symbol (bfd *abfd,
13995796c8dcSSimon Schubert void *filep,
14005796c8dcSSimon Schubert asymbol *symbol,
14015796c8dcSSimon Schubert bfd_print_symbol_type how)
14025796c8dcSSimon Schubert {
14035796c8dcSSimon Schubert FILE *file = (FILE *) filep;
14045796c8dcSSimon Schubert switch (how)
14055796c8dcSSimon Schubert {
14065796c8dcSSimon Schubert case bfd_print_symbol_name:
14075796c8dcSSimon Schubert fprintf (file, "%s", symbol->name);
14085796c8dcSSimon Schubert break;
14095796c8dcSSimon Schubert case bfd_print_symbol_more:
14105796c8dcSSimon Schubert fprintf (file, "elf ");
14115796c8dcSSimon Schubert bfd_fprintf_vma (abfd, file, symbol->value);
14125796c8dcSSimon Schubert fprintf (file, " %lx", (unsigned long) symbol->flags);
14135796c8dcSSimon Schubert break;
14145796c8dcSSimon Schubert case bfd_print_symbol_all:
14155796c8dcSSimon Schubert {
14165796c8dcSSimon Schubert const char *section_name;
14175796c8dcSSimon Schubert const char *name = NULL;
14185796c8dcSSimon Schubert const struct elf_backend_data *bed;
14195796c8dcSSimon Schubert unsigned char st_other;
14205796c8dcSSimon Schubert bfd_vma val;
14215796c8dcSSimon Schubert
14225796c8dcSSimon Schubert section_name = symbol->section ? symbol->section->name : "(*none*)";
14235796c8dcSSimon Schubert
14245796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
14255796c8dcSSimon Schubert if (bed->elf_backend_print_symbol_all)
14265796c8dcSSimon Schubert name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
14275796c8dcSSimon Schubert
14285796c8dcSSimon Schubert if (name == NULL)
14295796c8dcSSimon Schubert {
14305796c8dcSSimon Schubert name = symbol->name;
14315796c8dcSSimon Schubert bfd_print_symbol_vandf (abfd, file, symbol);
14325796c8dcSSimon Schubert }
14335796c8dcSSimon Schubert
14345796c8dcSSimon Schubert fprintf (file, " %s\t", section_name);
14355796c8dcSSimon Schubert /* Print the "other" value for a symbol. For common symbols,
14365796c8dcSSimon Schubert we've already printed the size; now print the alignment.
14375796c8dcSSimon Schubert For other symbols, we have no specified alignment, and
14385796c8dcSSimon Schubert we've printed the address; now print the size. */
14395796c8dcSSimon Schubert if (symbol->section && bfd_is_com_section (symbol->section))
14405796c8dcSSimon Schubert val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
14415796c8dcSSimon Schubert else
14425796c8dcSSimon Schubert val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
14435796c8dcSSimon Schubert bfd_fprintf_vma (abfd, file, val);
14445796c8dcSSimon Schubert
14455796c8dcSSimon Schubert /* If we have version information, print it. */
1446*ef5ccd6cSJohn Marino if (elf_dynversym (abfd) != 0
1447*ef5ccd6cSJohn Marino && (elf_dynverdef (abfd) != 0
1448*ef5ccd6cSJohn Marino || elf_dynverref (abfd) != 0))
14495796c8dcSSimon Schubert {
14505796c8dcSSimon Schubert unsigned int vernum;
14515796c8dcSSimon Schubert const char *version_string;
14525796c8dcSSimon Schubert
14535796c8dcSSimon Schubert vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION;
14545796c8dcSSimon Schubert
14555796c8dcSSimon Schubert if (vernum == 0)
14565796c8dcSSimon Schubert version_string = "";
14575796c8dcSSimon Schubert else if (vernum == 1)
14585796c8dcSSimon Schubert version_string = "Base";
14595796c8dcSSimon Schubert else if (vernum <= elf_tdata (abfd)->cverdefs)
14605796c8dcSSimon Schubert version_string =
14615796c8dcSSimon Schubert elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
14625796c8dcSSimon Schubert else
14635796c8dcSSimon Schubert {
14645796c8dcSSimon Schubert Elf_Internal_Verneed *t;
14655796c8dcSSimon Schubert
14665796c8dcSSimon Schubert version_string = "";
14675796c8dcSSimon Schubert for (t = elf_tdata (abfd)->verref;
14685796c8dcSSimon Schubert t != NULL;
14695796c8dcSSimon Schubert t = t->vn_nextref)
14705796c8dcSSimon Schubert {
14715796c8dcSSimon Schubert Elf_Internal_Vernaux *a;
14725796c8dcSSimon Schubert
14735796c8dcSSimon Schubert for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
14745796c8dcSSimon Schubert {
14755796c8dcSSimon Schubert if (a->vna_other == vernum)
14765796c8dcSSimon Schubert {
14775796c8dcSSimon Schubert version_string = a->vna_nodename;
14785796c8dcSSimon Schubert break;
14795796c8dcSSimon Schubert }
14805796c8dcSSimon Schubert }
14815796c8dcSSimon Schubert }
14825796c8dcSSimon Schubert }
14835796c8dcSSimon Schubert
14845796c8dcSSimon Schubert if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0)
14855796c8dcSSimon Schubert fprintf (file, " %-11s", version_string);
14865796c8dcSSimon Schubert else
14875796c8dcSSimon Schubert {
14885796c8dcSSimon Schubert int i;
14895796c8dcSSimon Schubert
14905796c8dcSSimon Schubert fprintf (file, " (%s)", version_string);
14915796c8dcSSimon Schubert for (i = 10 - strlen (version_string); i > 0; --i)
14925796c8dcSSimon Schubert putc (' ', file);
14935796c8dcSSimon Schubert }
14945796c8dcSSimon Schubert }
14955796c8dcSSimon Schubert
14965796c8dcSSimon Schubert /* If the st_other field is not zero, print it. */
14975796c8dcSSimon Schubert st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
14985796c8dcSSimon Schubert
14995796c8dcSSimon Schubert switch (st_other)
15005796c8dcSSimon Schubert {
15015796c8dcSSimon Schubert case 0: break;
15025796c8dcSSimon Schubert case STV_INTERNAL: fprintf (file, " .internal"); break;
15035796c8dcSSimon Schubert case STV_HIDDEN: fprintf (file, " .hidden"); break;
15045796c8dcSSimon Schubert case STV_PROTECTED: fprintf (file, " .protected"); break;
15055796c8dcSSimon Schubert default:
15065796c8dcSSimon Schubert /* Some other non-defined flags are also present, so print
15075796c8dcSSimon Schubert everything hex. */
15085796c8dcSSimon Schubert fprintf (file, " 0x%02x", (unsigned int) st_other);
15095796c8dcSSimon Schubert }
15105796c8dcSSimon Schubert
15115796c8dcSSimon Schubert fprintf (file, " %s", name);
15125796c8dcSSimon Schubert }
15135796c8dcSSimon Schubert break;
15145796c8dcSSimon Schubert }
15155796c8dcSSimon Schubert }
15165796c8dcSSimon Schubert
15175796c8dcSSimon Schubert /* Allocate an ELF string table--force the first byte to be zero. */
15185796c8dcSSimon Schubert
15195796c8dcSSimon Schubert struct bfd_strtab_hash *
_bfd_elf_stringtab_init(void)15205796c8dcSSimon Schubert _bfd_elf_stringtab_init (void)
15215796c8dcSSimon Schubert {
15225796c8dcSSimon Schubert struct bfd_strtab_hash *ret;
15235796c8dcSSimon Schubert
15245796c8dcSSimon Schubert ret = _bfd_stringtab_init ();
15255796c8dcSSimon Schubert if (ret != NULL)
15265796c8dcSSimon Schubert {
15275796c8dcSSimon Schubert bfd_size_type loc;
15285796c8dcSSimon Schubert
15295796c8dcSSimon Schubert loc = _bfd_stringtab_add (ret, "", TRUE, FALSE);
15305796c8dcSSimon Schubert BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1);
15315796c8dcSSimon Schubert if (loc == (bfd_size_type) -1)
15325796c8dcSSimon Schubert {
15335796c8dcSSimon Schubert _bfd_stringtab_free (ret);
15345796c8dcSSimon Schubert ret = NULL;
15355796c8dcSSimon Schubert }
15365796c8dcSSimon Schubert }
15375796c8dcSSimon Schubert return ret;
15385796c8dcSSimon Schubert }
15395796c8dcSSimon Schubert
15405796c8dcSSimon Schubert /* ELF .o/exec file reading */
15415796c8dcSSimon Schubert
15425796c8dcSSimon Schubert /* Create a new bfd section from an ELF section header. */
15435796c8dcSSimon Schubert
15445796c8dcSSimon Schubert bfd_boolean
bfd_section_from_shdr(bfd * abfd,unsigned int shindex)15455796c8dcSSimon Schubert bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
15465796c8dcSSimon Schubert {
15475796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
15485796c8dcSSimon Schubert Elf_Internal_Ehdr *ehdr;
15495796c8dcSSimon Schubert const struct elf_backend_data *bed;
15505796c8dcSSimon Schubert const char *name;
15515796c8dcSSimon Schubert
15525796c8dcSSimon Schubert if (shindex >= elf_numsections (abfd))
15535796c8dcSSimon Schubert return FALSE;
15545796c8dcSSimon Schubert
15555796c8dcSSimon Schubert hdr = elf_elfsections (abfd)[shindex];
15565796c8dcSSimon Schubert ehdr = elf_elfheader (abfd);
15575796c8dcSSimon Schubert name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
15585796c8dcSSimon Schubert hdr->sh_name);
15595796c8dcSSimon Schubert if (name == NULL)
15605796c8dcSSimon Schubert return FALSE;
15615796c8dcSSimon Schubert
15625796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
15635796c8dcSSimon Schubert switch (hdr->sh_type)
15645796c8dcSSimon Schubert {
15655796c8dcSSimon Schubert case SHT_NULL:
15665796c8dcSSimon Schubert /* Inactive section. Throw it away. */
15675796c8dcSSimon Schubert return TRUE;
15685796c8dcSSimon Schubert
15695796c8dcSSimon Schubert case SHT_PROGBITS: /* Normal section with contents. */
15705796c8dcSSimon Schubert case SHT_NOBITS: /* .bss section. */
15715796c8dcSSimon Schubert case SHT_HASH: /* .hash section. */
15725796c8dcSSimon Schubert case SHT_NOTE: /* .note section. */
15735796c8dcSSimon Schubert case SHT_INIT_ARRAY: /* .init_array section. */
15745796c8dcSSimon Schubert case SHT_FINI_ARRAY: /* .fini_array section. */
15755796c8dcSSimon Schubert case SHT_PREINIT_ARRAY: /* .preinit_array section. */
15765796c8dcSSimon Schubert case SHT_GNU_LIBLIST: /* .gnu.liblist section. */
15775796c8dcSSimon Schubert case SHT_GNU_HASH: /* .gnu.hash section. */
15785796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
15795796c8dcSSimon Schubert
15805796c8dcSSimon Schubert case SHT_DYNAMIC: /* Dynamic linking information. */
15815796c8dcSSimon Schubert if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
15825796c8dcSSimon Schubert return FALSE;
15835796c8dcSSimon Schubert if (hdr->sh_link > elf_numsections (abfd))
15845796c8dcSSimon Schubert {
1585cf7f2e2dSJohn Marino /* PR 10478: Accept Solaris binaries with a sh_link
15865796c8dcSSimon Schubert field set to SHN_BEFORE or SHN_AFTER. */
15875796c8dcSSimon Schubert switch (bfd_get_arch (abfd))
15885796c8dcSSimon Schubert {
1589cf7f2e2dSJohn Marino case bfd_arch_i386:
15905796c8dcSSimon Schubert case bfd_arch_sparc:
15915796c8dcSSimon Schubert if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
15925796c8dcSSimon Schubert || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
15935796c8dcSSimon Schubert break;
15945796c8dcSSimon Schubert /* Otherwise fall through. */
15955796c8dcSSimon Schubert default:
15965796c8dcSSimon Schubert return FALSE;
15975796c8dcSSimon Schubert }
15985796c8dcSSimon Schubert }
15995796c8dcSSimon Schubert else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
16005796c8dcSSimon Schubert return FALSE;
16015796c8dcSSimon Schubert else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
16025796c8dcSSimon Schubert {
16035796c8dcSSimon Schubert Elf_Internal_Shdr *dynsymhdr;
16045796c8dcSSimon Schubert
16055796c8dcSSimon Schubert /* The shared libraries distributed with hpux11 have a bogus
16065796c8dcSSimon Schubert sh_link field for the ".dynamic" section. Find the
16075796c8dcSSimon Schubert string table for the ".dynsym" section instead. */
16085796c8dcSSimon Schubert if (elf_dynsymtab (abfd) != 0)
16095796c8dcSSimon Schubert {
16105796c8dcSSimon Schubert dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
16115796c8dcSSimon Schubert hdr->sh_link = dynsymhdr->sh_link;
16125796c8dcSSimon Schubert }
16135796c8dcSSimon Schubert else
16145796c8dcSSimon Schubert {
16155796c8dcSSimon Schubert unsigned int i, num_sec;
16165796c8dcSSimon Schubert
16175796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
16185796c8dcSSimon Schubert for (i = 1; i < num_sec; i++)
16195796c8dcSSimon Schubert {
16205796c8dcSSimon Schubert dynsymhdr = elf_elfsections (abfd)[i];
16215796c8dcSSimon Schubert if (dynsymhdr->sh_type == SHT_DYNSYM)
16225796c8dcSSimon Schubert {
16235796c8dcSSimon Schubert hdr->sh_link = dynsymhdr->sh_link;
16245796c8dcSSimon Schubert break;
16255796c8dcSSimon Schubert }
16265796c8dcSSimon Schubert }
16275796c8dcSSimon Schubert }
16285796c8dcSSimon Schubert }
16295796c8dcSSimon Schubert break;
16305796c8dcSSimon Schubert
16315796c8dcSSimon Schubert case SHT_SYMTAB: /* A symbol table */
16325796c8dcSSimon Schubert if (elf_onesymtab (abfd) == shindex)
16335796c8dcSSimon Schubert return TRUE;
16345796c8dcSSimon Schubert
16355796c8dcSSimon Schubert if (hdr->sh_entsize != bed->s->sizeof_sym)
16365796c8dcSSimon Schubert return FALSE;
16375796c8dcSSimon Schubert if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
1638*ef5ccd6cSJohn Marino {
1639*ef5ccd6cSJohn Marino if (hdr->sh_size != 0)
16405796c8dcSSimon Schubert return FALSE;
1641*ef5ccd6cSJohn Marino /* Some assemblers erroneously set sh_info to one with a
1642*ef5ccd6cSJohn Marino zero sh_size. ld sees this as a global symbol count
1643*ef5ccd6cSJohn Marino of (unsigned) -1. Fix it here. */
1644*ef5ccd6cSJohn Marino hdr->sh_info = 0;
1645*ef5ccd6cSJohn Marino return TRUE;
1646*ef5ccd6cSJohn Marino }
16475796c8dcSSimon Schubert BFD_ASSERT (elf_onesymtab (abfd) == 0);
16485796c8dcSSimon Schubert elf_onesymtab (abfd) = shindex;
16495796c8dcSSimon Schubert elf_tdata (abfd)->symtab_hdr = *hdr;
16505796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
16515796c8dcSSimon Schubert abfd->flags |= HAS_SYMS;
16525796c8dcSSimon Schubert
16535796c8dcSSimon Schubert /* Sometimes a shared object will map in the symbol table. If
16545796c8dcSSimon Schubert SHF_ALLOC is set, and this is a shared object, then we also
16555796c8dcSSimon Schubert treat this section as a BFD section. We can not base the
16565796c8dcSSimon Schubert decision purely on SHF_ALLOC, because that flag is sometimes
16575796c8dcSSimon Schubert set in a relocatable object file, which would confuse the
16585796c8dcSSimon Schubert linker. */
16595796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_ALLOC) != 0
16605796c8dcSSimon Schubert && (abfd->flags & DYNAMIC) != 0
16615796c8dcSSimon Schubert && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
16625796c8dcSSimon Schubert shindex))
16635796c8dcSSimon Schubert return FALSE;
16645796c8dcSSimon Schubert
16655796c8dcSSimon Schubert /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
16665796c8dcSSimon Schubert can't read symbols without that section loaded as well. It
16675796c8dcSSimon Schubert is most likely specified by the next section header. */
16685796c8dcSSimon Schubert if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
16695796c8dcSSimon Schubert {
16705796c8dcSSimon Schubert unsigned int i, num_sec;
16715796c8dcSSimon Schubert
16725796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
16735796c8dcSSimon Schubert for (i = shindex + 1; i < num_sec; i++)
16745796c8dcSSimon Schubert {
16755796c8dcSSimon Schubert Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
16765796c8dcSSimon Schubert if (hdr2->sh_type == SHT_SYMTAB_SHNDX
16775796c8dcSSimon Schubert && hdr2->sh_link == shindex)
16785796c8dcSSimon Schubert break;
16795796c8dcSSimon Schubert }
16805796c8dcSSimon Schubert if (i == num_sec)
16815796c8dcSSimon Schubert for (i = 1; i < shindex; i++)
16825796c8dcSSimon Schubert {
16835796c8dcSSimon Schubert Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
16845796c8dcSSimon Schubert if (hdr2->sh_type == SHT_SYMTAB_SHNDX
16855796c8dcSSimon Schubert && hdr2->sh_link == shindex)
16865796c8dcSSimon Schubert break;
16875796c8dcSSimon Schubert }
16885796c8dcSSimon Schubert if (i != shindex)
16895796c8dcSSimon Schubert return bfd_section_from_shdr (abfd, i);
16905796c8dcSSimon Schubert }
16915796c8dcSSimon Schubert return TRUE;
16925796c8dcSSimon Schubert
16935796c8dcSSimon Schubert case SHT_DYNSYM: /* A dynamic symbol table */
16945796c8dcSSimon Schubert if (elf_dynsymtab (abfd) == shindex)
16955796c8dcSSimon Schubert return TRUE;
16965796c8dcSSimon Schubert
16975796c8dcSSimon Schubert if (hdr->sh_entsize != bed->s->sizeof_sym)
16985796c8dcSSimon Schubert return FALSE;
1699*ef5ccd6cSJohn Marino if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
1700*ef5ccd6cSJohn Marino {
1701*ef5ccd6cSJohn Marino if (hdr->sh_size != 0)
1702*ef5ccd6cSJohn Marino return FALSE;
1703*ef5ccd6cSJohn Marino /* Some linkers erroneously set sh_info to one with a
1704*ef5ccd6cSJohn Marino zero sh_size. ld sees this as a global symbol count
1705*ef5ccd6cSJohn Marino of (unsigned) -1. Fix it here. */
1706*ef5ccd6cSJohn Marino hdr->sh_info = 0;
1707*ef5ccd6cSJohn Marino return TRUE;
1708*ef5ccd6cSJohn Marino }
17095796c8dcSSimon Schubert BFD_ASSERT (elf_dynsymtab (abfd) == 0);
17105796c8dcSSimon Schubert elf_dynsymtab (abfd) = shindex;
17115796c8dcSSimon Schubert elf_tdata (abfd)->dynsymtab_hdr = *hdr;
17125796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
17135796c8dcSSimon Schubert abfd->flags |= HAS_SYMS;
17145796c8dcSSimon Schubert
17155796c8dcSSimon Schubert /* Besides being a symbol table, we also treat this as a regular
17165796c8dcSSimon Schubert section, so that objcopy can handle it. */
17175796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
17185796c8dcSSimon Schubert
17195796c8dcSSimon Schubert case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */
17205796c8dcSSimon Schubert if (elf_symtab_shndx (abfd) == shindex)
17215796c8dcSSimon Schubert return TRUE;
17225796c8dcSSimon Schubert
17235796c8dcSSimon Schubert BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
17245796c8dcSSimon Schubert elf_symtab_shndx (abfd) = shindex;
17255796c8dcSSimon Schubert elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
17265796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
17275796c8dcSSimon Schubert return TRUE;
17285796c8dcSSimon Schubert
17295796c8dcSSimon Schubert case SHT_STRTAB: /* A string table */
17305796c8dcSSimon Schubert if (hdr->bfd_section != NULL)
17315796c8dcSSimon Schubert return TRUE;
17325796c8dcSSimon Schubert if (ehdr->e_shstrndx == shindex)
17335796c8dcSSimon Schubert {
17345796c8dcSSimon Schubert elf_tdata (abfd)->shstrtab_hdr = *hdr;
17355796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
17365796c8dcSSimon Schubert return TRUE;
17375796c8dcSSimon Schubert }
17385796c8dcSSimon Schubert if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
17395796c8dcSSimon Schubert {
17405796c8dcSSimon Schubert symtab_strtab:
17415796c8dcSSimon Schubert elf_tdata (abfd)->strtab_hdr = *hdr;
17425796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
17435796c8dcSSimon Schubert return TRUE;
17445796c8dcSSimon Schubert }
17455796c8dcSSimon Schubert if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
17465796c8dcSSimon Schubert {
17475796c8dcSSimon Schubert dynsymtab_strtab:
17485796c8dcSSimon Schubert elf_tdata (abfd)->dynstrtab_hdr = *hdr;
17495796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->dynstrtab_hdr;
17505796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = hdr;
17515796c8dcSSimon Schubert /* We also treat this as a regular section, so that objcopy
17525796c8dcSSimon Schubert can handle it. */
17535796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
17545796c8dcSSimon Schubert shindex);
17555796c8dcSSimon Schubert }
17565796c8dcSSimon Schubert
17575796c8dcSSimon Schubert /* If the string table isn't one of the above, then treat it as a
17585796c8dcSSimon Schubert regular section. We need to scan all the headers to be sure,
17595796c8dcSSimon Schubert just in case this strtab section appeared before the above. */
17605796c8dcSSimon Schubert if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
17615796c8dcSSimon Schubert {
17625796c8dcSSimon Schubert unsigned int i, num_sec;
17635796c8dcSSimon Schubert
17645796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
17655796c8dcSSimon Schubert for (i = 1; i < num_sec; i++)
17665796c8dcSSimon Schubert {
17675796c8dcSSimon Schubert Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
17685796c8dcSSimon Schubert if (hdr2->sh_link == shindex)
17695796c8dcSSimon Schubert {
17705796c8dcSSimon Schubert /* Prevent endless recursion on broken objects. */
17715796c8dcSSimon Schubert if (i == shindex)
17725796c8dcSSimon Schubert return FALSE;
17735796c8dcSSimon Schubert if (! bfd_section_from_shdr (abfd, i))
17745796c8dcSSimon Schubert return FALSE;
17755796c8dcSSimon Schubert if (elf_onesymtab (abfd) == i)
17765796c8dcSSimon Schubert goto symtab_strtab;
17775796c8dcSSimon Schubert if (elf_dynsymtab (abfd) == i)
17785796c8dcSSimon Schubert goto dynsymtab_strtab;
17795796c8dcSSimon Schubert }
17805796c8dcSSimon Schubert }
17815796c8dcSSimon Schubert }
17825796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
17835796c8dcSSimon Schubert
17845796c8dcSSimon Schubert case SHT_REL:
17855796c8dcSSimon Schubert case SHT_RELA:
17865796c8dcSSimon Schubert /* *These* do a lot of work -- but build no sections! */
17875796c8dcSSimon Schubert {
17885796c8dcSSimon Schubert asection *target_sect;
1789c50c785cSJohn Marino Elf_Internal_Shdr *hdr2, **p_hdr;
17905796c8dcSSimon Schubert unsigned int num_sec = elf_numsections (abfd);
1791c50c785cSJohn Marino struct bfd_elf_section_data *esdt;
1792c50c785cSJohn Marino bfd_size_type amt;
17935796c8dcSSimon Schubert
17945796c8dcSSimon Schubert if (hdr->sh_entsize
17955796c8dcSSimon Schubert != (bfd_size_type) (hdr->sh_type == SHT_REL
17965796c8dcSSimon Schubert ? bed->s->sizeof_rel : bed->s->sizeof_rela))
17975796c8dcSSimon Schubert return FALSE;
17985796c8dcSSimon Schubert
17995796c8dcSSimon Schubert /* Check for a bogus link to avoid crashing. */
18005796c8dcSSimon Schubert if (hdr->sh_link >= num_sec)
18015796c8dcSSimon Schubert {
18025796c8dcSSimon Schubert ((*_bfd_error_handler)
18035796c8dcSSimon Schubert (_("%B: invalid link %lu for reloc section %s (index %u)"),
18045796c8dcSSimon Schubert abfd, hdr->sh_link, name, shindex));
18055796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
18065796c8dcSSimon Schubert shindex);
18075796c8dcSSimon Schubert }
18085796c8dcSSimon Schubert
18095796c8dcSSimon Schubert /* For some incomprehensible reason Oracle distributes
18105796c8dcSSimon Schubert libraries for Solaris in which some of the objects have
18115796c8dcSSimon Schubert bogus sh_link fields. It would be nice if we could just
18125796c8dcSSimon Schubert reject them, but, unfortunately, some people need to use
18135796c8dcSSimon Schubert them. We scan through the section headers; if we find only
18145796c8dcSSimon Schubert one suitable symbol table, we clobber the sh_link to point
18155796c8dcSSimon Schubert to it. I hope this doesn't break anything.
18165796c8dcSSimon Schubert
18175796c8dcSSimon Schubert Don't do it on executable nor shared library. */
18185796c8dcSSimon Schubert if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0
18195796c8dcSSimon Schubert && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
18205796c8dcSSimon Schubert && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
18215796c8dcSSimon Schubert {
18225796c8dcSSimon Schubert unsigned int scan;
18235796c8dcSSimon Schubert int found;
18245796c8dcSSimon Schubert
18255796c8dcSSimon Schubert found = 0;
18265796c8dcSSimon Schubert for (scan = 1; scan < num_sec; scan++)
18275796c8dcSSimon Schubert {
18285796c8dcSSimon Schubert if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
18295796c8dcSSimon Schubert || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
18305796c8dcSSimon Schubert {
18315796c8dcSSimon Schubert if (found != 0)
18325796c8dcSSimon Schubert {
18335796c8dcSSimon Schubert found = 0;
18345796c8dcSSimon Schubert break;
18355796c8dcSSimon Schubert }
18365796c8dcSSimon Schubert found = scan;
18375796c8dcSSimon Schubert }
18385796c8dcSSimon Schubert }
18395796c8dcSSimon Schubert if (found != 0)
18405796c8dcSSimon Schubert hdr->sh_link = found;
18415796c8dcSSimon Schubert }
18425796c8dcSSimon Schubert
18435796c8dcSSimon Schubert /* Get the symbol table. */
18445796c8dcSSimon Schubert if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
18455796c8dcSSimon Schubert || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
18465796c8dcSSimon Schubert && ! bfd_section_from_shdr (abfd, hdr->sh_link))
18475796c8dcSSimon Schubert return FALSE;
18485796c8dcSSimon Schubert
18495796c8dcSSimon Schubert /* If this reloc section does not use the main symbol table we
18505796c8dcSSimon Schubert don't treat it as a reloc section. BFD can't adequately
18515796c8dcSSimon Schubert represent such a section, so at least for now, we don't
18525796c8dcSSimon Schubert try. We just present it as a normal section. We also
18535796c8dcSSimon Schubert can't use it as a reloc section if it points to the null
18545796c8dcSSimon Schubert section, an invalid section, another reloc section, or its
18555796c8dcSSimon Schubert sh_link points to the null section. */
18565796c8dcSSimon Schubert if (hdr->sh_link != elf_onesymtab (abfd)
18575796c8dcSSimon Schubert || hdr->sh_link == SHN_UNDEF
18585796c8dcSSimon Schubert || hdr->sh_info == SHN_UNDEF
18595796c8dcSSimon Schubert || hdr->sh_info >= num_sec
18605796c8dcSSimon Schubert || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
18615796c8dcSSimon Schubert || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
18625796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
18635796c8dcSSimon Schubert shindex);
18645796c8dcSSimon Schubert
18655796c8dcSSimon Schubert if (! bfd_section_from_shdr (abfd, hdr->sh_info))
18665796c8dcSSimon Schubert return FALSE;
18675796c8dcSSimon Schubert target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
18685796c8dcSSimon Schubert if (target_sect == NULL)
18695796c8dcSSimon Schubert return FALSE;
18705796c8dcSSimon Schubert
1871c50c785cSJohn Marino esdt = elf_section_data (target_sect);
1872c50c785cSJohn Marino if (hdr->sh_type == SHT_RELA)
1873c50c785cSJohn Marino p_hdr = &esdt->rela.hdr;
18745796c8dcSSimon Schubert else
1875c50c785cSJohn Marino p_hdr = &esdt->rel.hdr;
1876c50c785cSJohn Marino
1877c50c785cSJohn Marino BFD_ASSERT (*p_hdr == NULL);
18785796c8dcSSimon Schubert amt = sizeof (*hdr2);
18795796c8dcSSimon Schubert hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
18805796c8dcSSimon Schubert if (hdr2 == NULL)
18815796c8dcSSimon Schubert return FALSE;
18825796c8dcSSimon Schubert *hdr2 = *hdr;
1883c50c785cSJohn Marino *p_hdr = hdr2;
18845796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = hdr2;
18855796c8dcSSimon Schubert target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
18865796c8dcSSimon Schubert target_sect->flags |= SEC_RELOC;
18875796c8dcSSimon Schubert target_sect->relocation = NULL;
18885796c8dcSSimon Schubert target_sect->rel_filepos = hdr->sh_offset;
18895796c8dcSSimon Schubert /* In the section to which the relocations apply, mark whether
18905796c8dcSSimon Schubert its relocations are of the REL or RELA variety. */
18915796c8dcSSimon Schubert if (hdr->sh_size != 0)
1892c50c785cSJohn Marino {
1893c50c785cSJohn Marino if (hdr->sh_type == SHT_RELA)
1894c50c785cSJohn Marino target_sect->use_rela_p = 1;
1895c50c785cSJohn Marino }
18965796c8dcSSimon Schubert abfd->flags |= HAS_RELOC;
18975796c8dcSSimon Schubert return TRUE;
18985796c8dcSSimon Schubert }
18995796c8dcSSimon Schubert
19005796c8dcSSimon Schubert case SHT_GNU_verdef:
19015796c8dcSSimon Schubert elf_dynverdef (abfd) = shindex;
19025796c8dcSSimon Schubert elf_tdata (abfd)->dynverdef_hdr = *hdr;
19035796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
19045796c8dcSSimon Schubert
19055796c8dcSSimon Schubert case SHT_GNU_versym:
19065796c8dcSSimon Schubert if (hdr->sh_entsize != sizeof (Elf_External_Versym))
19075796c8dcSSimon Schubert return FALSE;
19085796c8dcSSimon Schubert elf_dynversym (abfd) = shindex;
19095796c8dcSSimon Schubert elf_tdata (abfd)->dynversym_hdr = *hdr;
19105796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
19115796c8dcSSimon Schubert
19125796c8dcSSimon Schubert case SHT_GNU_verneed:
19135796c8dcSSimon Schubert elf_dynverref (abfd) = shindex;
19145796c8dcSSimon Schubert elf_tdata (abfd)->dynverref_hdr = *hdr;
19155796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
19165796c8dcSSimon Schubert
19175796c8dcSSimon Schubert case SHT_SHLIB:
19185796c8dcSSimon Schubert return TRUE;
19195796c8dcSSimon Schubert
19205796c8dcSSimon Schubert case SHT_GROUP:
1921*ef5ccd6cSJohn Marino if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE))
19225796c8dcSSimon Schubert return FALSE;
19235796c8dcSSimon Schubert if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
19245796c8dcSSimon Schubert return FALSE;
19255796c8dcSSimon Schubert if (hdr->contents != NULL)
19265796c8dcSSimon Schubert {
19275796c8dcSSimon Schubert Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
19285796c8dcSSimon Schubert unsigned int n_elt = hdr->sh_size / GRP_ENTRY_SIZE;
19295796c8dcSSimon Schubert asection *s;
19305796c8dcSSimon Schubert
19315796c8dcSSimon Schubert if (idx->flags & GRP_COMDAT)
19325796c8dcSSimon Schubert hdr->bfd_section->flags
19335796c8dcSSimon Schubert |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
19345796c8dcSSimon Schubert
19355796c8dcSSimon Schubert /* We try to keep the same section order as it comes in. */
19365796c8dcSSimon Schubert idx += n_elt;
19375796c8dcSSimon Schubert while (--n_elt != 0)
19385796c8dcSSimon Schubert {
19395796c8dcSSimon Schubert --idx;
19405796c8dcSSimon Schubert
19415796c8dcSSimon Schubert if (idx->shdr != NULL
19425796c8dcSSimon Schubert && (s = idx->shdr->bfd_section) != NULL
19435796c8dcSSimon Schubert && elf_next_in_group (s) != NULL)
19445796c8dcSSimon Schubert {
19455796c8dcSSimon Schubert elf_next_in_group (hdr->bfd_section) = s;
19465796c8dcSSimon Schubert break;
19475796c8dcSSimon Schubert }
19485796c8dcSSimon Schubert }
19495796c8dcSSimon Schubert }
19505796c8dcSSimon Schubert break;
19515796c8dcSSimon Schubert
19525796c8dcSSimon Schubert default:
19535796c8dcSSimon Schubert /* Possibly an attributes section. */
19545796c8dcSSimon Schubert if (hdr->sh_type == SHT_GNU_ATTRIBUTES
19555796c8dcSSimon Schubert || hdr->sh_type == bed->obj_attrs_section_type)
19565796c8dcSSimon Schubert {
19575796c8dcSSimon Schubert if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
19585796c8dcSSimon Schubert return FALSE;
19595796c8dcSSimon Schubert _bfd_elf_parse_attributes (abfd, hdr);
19605796c8dcSSimon Schubert return TRUE;
19615796c8dcSSimon Schubert }
19625796c8dcSSimon Schubert
19635796c8dcSSimon Schubert /* Check for any processor-specific section types. */
19645796c8dcSSimon Schubert if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
19655796c8dcSSimon Schubert return TRUE;
19665796c8dcSSimon Schubert
19675796c8dcSSimon Schubert if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
19685796c8dcSSimon Schubert {
19695796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_ALLOC) != 0)
19705796c8dcSSimon Schubert /* FIXME: How to properly handle allocated section reserved
19715796c8dcSSimon Schubert for applications? */
19725796c8dcSSimon Schubert (*_bfd_error_handler)
19735796c8dcSSimon Schubert (_("%B: don't know how to handle allocated, application "
19745796c8dcSSimon Schubert "specific section `%s' [0x%8x]"),
19755796c8dcSSimon Schubert abfd, name, hdr->sh_type);
19765796c8dcSSimon Schubert else
19775796c8dcSSimon Schubert /* Allow sections reserved for applications. */
19785796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
19795796c8dcSSimon Schubert shindex);
19805796c8dcSSimon Schubert }
19815796c8dcSSimon Schubert else if (hdr->sh_type >= SHT_LOPROC
19825796c8dcSSimon Schubert && hdr->sh_type <= SHT_HIPROC)
19835796c8dcSSimon Schubert /* FIXME: We should handle this section. */
19845796c8dcSSimon Schubert (*_bfd_error_handler)
19855796c8dcSSimon Schubert (_("%B: don't know how to handle processor specific section "
19865796c8dcSSimon Schubert "`%s' [0x%8x]"),
19875796c8dcSSimon Schubert abfd, name, hdr->sh_type);
19885796c8dcSSimon Schubert else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
19895796c8dcSSimon Schubert {
19905796c8dcSSimon Schubert /* Unrecognised OS-specific sections. */
19915796c8dcSSimon Schubert if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0)
19925796c8dcSSimon Schubert /* SHF_OS_NONCONFORMING indicates that special knowledge is
19935796c8dcSSimon Schubert required to correctly process the section and the file should
19945796c8dcSSimon Schubert be rejected with an error message. */
19955796c8dcSSimon Schubert (*_bfd_error_handler)
19965796c8dcSSimon Schubert (_("%B: don't know how to handle OS specific section "
19975796c8dcSSimon Schubert "`%s' [0x%8x]"),
19985796c8dcSSimon Schubert abfd, name, hdr->sh_type);
19995796c8dcSSimon Schubert else
20005796c8dcSSimon Schubert /* Otherwise it should be processed. */
20015796c8dcSSimon Schubert return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
20025796c8dcSSimon Schubert }
20035796c8dcSSimon Schubert else
20045796c8dcSSimon Schubert /* FIXME: We should handle this section. */
20055796c8dcSSimon Schubert (*_bfd_error_handler)
20065796c8dcSSimon Schubert (_("%B: don't know how to handle section `%s' [0x%8x]"),
20075796c8dcSSimon Schubert abfd, name, hdr->sh_type);
20085796c8dcSSimon Schubert
20095796c8dcSSimon Schubert return FALSE;
20105796c8dcSSimon Schubert }
20115796c8dcSSimon Schubert
20125796c8dcSSimon Schubert return TRUE;
20135796c8dcSSimon Schubert }
20145796c8dcSSimon Schubert
20155796c8dcSSimon Schubert /* Return the local symbol specified by ABFD, R_SYMNDX. */
20165796c8dcSSimon Schubert
20175796c8dcSSimon Schubert Elf_Internal_Sym *
bfd_sym_from_r_symndx(struct sym_cache * cache,bfd * abfd,unsigned long r_symndx)20185796c8dcSSimon Schubert bfd_sym_from_r_symndx (struct sym_cache *cache,
20195796c8dcSSimon Schubert bfd *abfd,
20205796c8dcSSimon Schubert unsigned long r_symndx)
20215796c8dcSSimon Schubert {
20225796c8dcSSimon Schubert unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
20235796c8dcSSimon Schubert
20245796c8dcSSimon Schubert if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
20255796c8dcSSimon Schubert {
20265796c8dcSSimon Schubert Elf_Internal_Shdr *symtab_hdr;
20275796c8dcSSimon Schubert unsigned char esym[sizeof (Elf64_External_Sym)];
20285796c8dcSSimon Schubert Elf_External_Sym_Shndx eshndx;
20295796c8dcSSimon Schubert
20305796c8dcSSimon Schubert symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
20315796c8dcSSimon Schubert if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
20325796c8dcSSimon Schubert &cache->sym[ent], esym, &eshndx) == NULL)
20335796c8dcSSimon Schubert return NULL;
20345796c8dcSSimon Schubert
20355796c8dcSSimon Schubert if (cache->abfd != abfd)
20365796c8dcSSimon Schubert {
20375796c8dcSSimon Schubert memset (cache->indx, -1, sizeof (cache->indx));
20385796c8dcSSimon Schubert cache->abfd = abfd;
20395796c8dcSSimon Schubert }
20405796c8dcSSimon Schubert cache->indx[ent] = r_symndx;
20415796c8dcSSimon Schubert }
20425796c8dcSSimon Schubert
20435796c8dcSSimon Schubert return &cache->sym[ent];
20445796c8dcSSimon Schubert }
20455796c8dcSSimon Schubert
20465796c8dcSSimon Schubert /* Given an ELF section number, retrieve the corresponding BFD
20475796c8dcSSimon Schubert section. */
20485796c8dcSSimon Schubert
20495796c8dcSSimon Schubert asection *
bfd_section_from_elf_index(bfd * abfd,unsigned int sec_index)2050cf7f2e2dSJohn Marino bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index)
20515796c8dcSSimon Schubert {
2052cf7f2e2dSJohn Marino if (sec_index >= elf_numsections (abfd))
20535796c8dcSSimon Schubert return NULL;
2054cf7f2e2dSJohn Marino return elf_elfsections (abfd)[sec_index]->bfd_section;
20555796c8dcSSimon Schubert }
20565796c8dcSSimon Schubert
20575796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_b[] =
20585796c8dcSSimon Schubert {
20595796c8dcSSimon Schubert { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
20605796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
20615796c8dcSSimon Schubert };
20625796c8dcSSimon Schubert
20635796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_c[] =
20645796c8dcSSimon Schubert {
20655796c8dcSSimon Schubert { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
20665796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
20675796c8dcSSimon Schubert };
20685796c8dcSSimon Schubert
20695796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_d[] =
20705796c8dcSSimon Schubert {
20715796c8dcSSimon Schubert { STRING_COMMA_LEN (".data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
20725796c8dcSSimon Schubert { STRING_COMMA_LEN (".data1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2073*ef5ccd6cSJohn Marino /* There are more DWARF sections than these, but they needn't be added here
2074*ef5ccd6cSJohn Marino unless you have to cope with broken compilers that don't emit section
2075*ef5ccd6cSJohn Marino attributes or you want to help the user writing assembler. */
20765796c8dcSSimon Schubert { STRING_COMMA_LEN (".debug"), 0, SHT_PROGBITS, 0 },
20775796c8dcSSimon Schubert { STRING_COMMA_LEN (".debug_line"), 0, SHT_PROGBITS, 0 },
20785796c8dcSSimon Schubert { STRING_COMMA_LEN (".debug_info"), 0, SHT_PROGBITS, 0 },
20795796c8dcSSimon Schubert { STRING_COMMA_LEN (".debug_abbrev"), 0, SHT_PROGBITS, 0 },
20805796c8dcSSimon Schubert { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
20815796c8dcSSimon Schubert { STRING_COMMA_LEN (".dynamic"), 0, SHT_DYNAMIC, SHF_ALLOC },
20825796c8dcSSimon Schubert { STRING_COMMA_LEN (".dynstr"), 0, SHT_STRTAB, SHF_ALLOC },
20835796c8dcSSimon Schubert { STRING_COMMA_LEN (".dynsym"), 0, SHT_DYNSYM, SHF_ALLOC },
20845796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
20855796c8dcSSimon Schubert };
20865796c8dcSSimon Schubert
20875796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_f[] =
20885796c8dcSSimon Schubert {
20895796c8dcSSimon Schubert { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
20905796c8dcSSimon Schubert { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
20915796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
20925796c8dcSSimon Schubert };
20935796c8dcSSimon Schubert
20945796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_g[] =
20955796c8dcSSimon Schubert {
20965796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
2097c50c785cSJohn Marino { STRING_COMMA_LEN (".gnu.lto_"), -1, SHT_PROGBITS, SHF_EXCLUDE },
20985796c8dcSSimon Schubert { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
20995796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.version"), 0, SHT_GNU_versym, 0 },
21005796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.version_d"), 0, SHT_GNU_verdef, 0 },
21015796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.version_r"), 0, SHT_GNU_verneed, 0 },
21025796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.liblist"), 0, SHT_GNU_LIBLIST, SHF_ALLOC },
21035796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.conflict"), 0, SHT_RELA, SHF_ALLOC },
21045796c8dcSSimon Schubert { STRING_COMMA_LEN (".gnu.hash"), 0, SHT_GNU_HASH, SHF_ALLOC },
21055796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21065796c8dcSSimon Schubert };
21075796c8dcSSimon Schubert
21085796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_h[] =
21095796c8dcSSimon Schubert {
21105796c8dcSSimon Schubert { STRING_COMMA_LEN (".hash"), 0, SHT_HASH, SHF_ALLOC },
21115796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21125796c8dcSSimon Schubert };
21135796c8dcSSimon Schubert
21145796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_i[] =
21155796c8dcSSimon Schubert {
21165796c8dcSSimon Schubert { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
21175796c8dcSSimon Schubert { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
21185796c8dcSSimon Schubert { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 },
21195796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21205796c8dcSSimon Schubert };
21215796c8dcSSimon Schubert
21225796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_l[] =
21235796c8dcSSimon Schubert {
21245796c8dcSSimon Schubert { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
21255796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21265796c8dcSSimon Schubert };
21275796c8dcSSimon Schubert
21285796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_n[] =
21295796c8dcSSimon Schubert {
21305796c8dcSSimon Schubert { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
21315796c8dcSSimon Schubert { STRING_COMMA_LEN (".note"), -1, SHT_NOTE, 0 },
21325796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21335796c8dcSSimon Schubert };
21345796c8dcSSimon Schubert
21355796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_p[] =
21365796c8dcSSimon Schubert {
21375796c8dcSSimon Schubert { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
21385796c8dcSSimon Schubert { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
21395796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21405796c8dcSSimon Schubert };
21415796c8dcSSimon Schubert
21425796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_r[] =
21435796c8dcSSimon Schubert {
21445796c8dcSSimon Schubert { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
21455796c8dcSSimon Schubert { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
21465796c8dcSSimon Schubert { STRING_COMMA_LEN (".rela"), -1, SHT_RELA, 0 },
21475796c8dcSSimon Schubert { STRING_COMMA_LEN (".rel"), -1, SHT_REL, 0 },
21485796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21495796c8dcSSimon Schubert };
21505796c8dcSSimon Schubert
21515796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_s[] =
21525796c8dcSSimon Schubert {
21535796c8dcSSimon Schubert { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
21545796c8dcSSimon Schubert { STRING_COMMA_LEN (".strtab"), 0, SHT_STRTAB, 0 },
21555796c8dcSSimon Schubert { STRING_COMMA_LEN (".symtab"), 0, SHT_SYMTAB, 0 },
21565796c8dcSSimon Schubert /* See struct bfd_elf_special_section declaration for the semantics of
21575796c8dcSSimon Schubert this special case where .prefix_length != strlen (.prefix). */
21585796c8dcSSimon Schubert { ".stabstr", 5, 3, SHT_STRTAB, 0 },
21595796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21605796c8dcSSimon Schubert };
21615796c8dcSSimon Schubert
21625796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_t[] =
21635796c8dcSSimon Schubert {
21645796c8dcSSimon Schubert { STRING_COMMA_LEN (".text"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
21655796c8dcSSimon Schubert { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
21665796c8dcSSimon Schubert { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
21675796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21685796c8dcSSimon Schubert };
21695796c8dcSSimon Schubert
21705796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_z[] =
21715796c8dcSSimon Schubert {
21725796c8dcSSimon Schubert { STRING_COMMA_LEN (".zdebug_line"), 0, SHT_PROGBITS, 0 },
21735796c8dcSSimon Schubert { STRING_COMMA_LEN (".zdebug_info"), 0, SHT_PROGBITS, 0 },
21745796c8dcSSimon Schubert { STRING_COMMA_LEN (".zdebug_abbrev"), 0, SHT_PROGBITS, 0 },
21755796c8dcSSimon Schubert { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
21765796c8dcSSimon Schubert { NULL, 0, 0, 0, 0 }
21775796c8dcSSimon Schubert };
21785796c8dcSSimon Schubert
2179a45ae5f8SJohn Marino static const struct bfd_elf_special_section * const special_sections[] =
21805796c8dcSSimon Schubert {
21815796c8dcSSimon Schubert special_sections_b, /* 'b' */
21825796c8dcSSimon Schubert special_sections_c, /* 'c' */
21835796c8dcSSimon Schubert special_sections_d, /* 'd' */
21845796c8dcSSimon Schubert NULL, /* 'e' */
21855796c8dcSSimon Schubert special_sections_f, /* 'f' */
21865796c8dcSSimon Schubert special_sections_g, /* 'g' */
21875796c8dcSSimon Schubert special_sections_h, /* 'h' */
21885796c8dcSSimon Schubert special_sections_i, /* 'i' */
21895796c8dcSSimon Schubert NULL, /* 'j' */
21905796c8dcSSimon Schubert NULL, /* 'k' */
21915796c8dcSSimon Schubert special_sections_l, /* 'l' */
21925796c8dcSSimon Schubert NULL, /* 'm' */
21935796c8dcSSimon Schubert special_sections_n, /* 'n' */
21945796c8dcSSimon Schubert NULL, /* 'o' */
21955796c8dcSSimon Schubert special_sections_p, /* 'p' */
21965796c8dcSSimon Schubert NULL, /* 'q' */
21975796c8dcSSimon Schubert special_sections_r, /* 'r' */
21985796c8dcSSimon Schubert special_sections_s, /* 's' */
21995796c8dcSSimon Schubert special_sections_t, /* 't' */
22005796c8dcSSimon Schubert NULL, /* 'u' */
22015796c8dcSSimon Schubert NULL, /* 'v' */
22025796c8dcSSimon Schubert NULL, /* 'w' */
22035796c8dcSSimon Schubert NULL, /* 'x' */
22045796c8dcSSimon Schubert NULL, /* 'y' */
22055796c8dcSSimon Schubert special_sections_z /* 'z' */
22065796c8dcSSimon Schubert };
22075796c8dcSSimon Schubert
22085796c8dcSSimon Schubert const struct bfd_elf_special_section *
_bfd_elf_get_special_section(const char * name,const struct bfd_elf_special_section * spec,unsigned int rela)22095796c8dcSSimon Schubert _bfd_elf_get_special_section (const char *name,
22105796c8dcSSimon Schubert const struct bfd_elf_special_section *spec,
22115796c8dcSSimon Schubert unsigned int rela)
22125796c8dcSSimon Schubert {
22135796c8dcSSimon Schubert int i;
22145796c8dcSSimon Schubert int len;
22155796c8dcSSimon Schubert
22165796c8dcSSimon Schubert len = strlen (name);
22175796c8dcSSimon Schubert
22185796c8dcSSimon Schubert for (i = 0; spec[i].prefix != NULL; i++)
22195796c8dcSSimon Schubert {
22205796c8dcSSimon Schubert int suffix_len;
22215796c8dcSSimon Schubert int prefix_len = spec[i].prefix_length;
22225796c8dcSSimon Schubert
22235796c8dcSSimon Schubert if (len < prefix_len)
22245796c8dcSSimon Schubert continue;
22255796c8dcSSimon Schubert if (memcmp (name, spec[i].prefix, prefix_len) != 0)
22265796c8dcSSimon Schubert continue;
22275796c8dcSSimon Schubert
22285796c8dcSSimon Schubert suffix_len = spec[i].suffix_length;
22295796c8dcSSimon Schubert if (suffix_len <= 0)
22305796c8dcSSimon Schubert {
22315796c8dcSSimon Schubert if (name[prefix_len] != 0)
22325796c8dcSSimon Schubert {
22335796c8dcSSimon Schubert if (suffix_len == 0)
22345796c8dcSSimon Schubert continue;
22355796c8dcSSimon Schubert if (name[prefix_len] != '.'
22365796c8dcSSimon Schubert && (suffix_len == -2
22375796c8dcSSimon Schubert || (rela && spec[i].type == SHT_REL)))
22385796c8dcSSimon Schubert continue;
22395796c8dcSSimon Schubert }
22405796c8dcSSimon Schubert }
22415796c8dcSSimon Schubert else
22425796c8dcSSimon Schubert {
22435796c8dcSSimon Schubert if (len < prefix_len + suffix_len)
22445796c8dcSSimon Schubert continue;
22455796c8dcSSimon Schubert if (memcmp (name + len - suffix_len,
22465796c8dcSSimon Schubert spec[i].prefix + prefix_len,
22475796c8dcSSimon Schubert suffix_len) != 0)
22485796c8dcSSimon Schubert continue;
22495796c8dcSSimon Schubert }
22505796c8dcSSimon Schubert return &spec[i];
22515796c8dcSSimon Schubert }
22525796c8dcSSimon Schubert
22535796c8dcSSimon Schubert return NULL;
22545796c8dcSSimon Schubert }
22555796c8dcSSimon Schubert
22565796c8dcSSimon Schubert const struct bfd_elf_special_section *
_bfd_elf_get_sec_type_attr(bfd * abfd,asection * sec)22575796c8dcSSimon Schubert _bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
22585796c8dcSSimon Schubert {
22595796c8dcSSimon Schubert int i;
22605796c8dcSSimon Schubert const struct bfd_elf_special_section *spec;
22615796c8dcSSimon Schubert const struct elf_backend_data *bed;
22625796c8dcSSimon Schubert
22635796c8dcSSimon Schubert /* See if this is one of the special sections. */
22645796c8dcSSimon Schubert if (sec->name == NULL)
22655796c8dcSSimon Schubert return NULL;
22665796c8dcSSimon Schubert
22675796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
22685796c8dcSSimon Schubert spec = bed->special_sections;
22695796c8dcSSimon Schubert if (spec)
22705796c8dcSSimon Schubert {
22715796c8dcSSimon Schubert spec = _bfd_elf_get_special_section (sec->name,
22725796c8dcSSimon Schubert bed->special_sections,
22735796c8dcSSimon Schubert sec->use_rela_p);
22745796c8dcSSimon Schubert if (spec != NULL)
22755796c8dcSSimon Schubert return spec;
22765796c8dcSSimon Schubert }
22775796c8dcSSimon Schubert
22785796c8dcSSimon Schubert if (sec->name[0] != '.')
22795796c8dcSSimon Schubert return NULL;
22805796c8dcSSimon Schubert
22815796c8dcSSimon Schubert i = sec->name[1] - 'b';
22825796c8dcSSimon Schubert if (i < 0 || i > 'z' - 'b')
22835796c8dcSSimon Schubert return NULL;
22845796c8dcSSimon Schubert
22855796c8dcSSimon Schubert spec = special_sections[i];
22865796c8dcSSimon Schubert
22875796c8dcSSimon Schubert if (spec == NULL)
22885796c8dcSSimon Schubert return NULL;
22895796c8dcSSimon Schubert
22905796c8dcSSimon Schubert return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
22915796c8dcSSimon Schubert }
22925796c8dcSSimon Schubert
22935796c8dcSSimon Schubert bfd_boolean
_bfd_elf_new_section_hook(bfd * abfd,asection * sec)22945796c8dcSSimon Schubert _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
22955796c8dcSSimon Schubert {
22965796c8dcSSimon Schubert struct bfd_elf_section_data *sdata;
22975796c8dcSSimon Schubert const struct elf_backend_data *bed;
22985796c8dcSSimon Schubert const struct bfd_elf_special_section *ssect;
22995796c8dcSSimon Schubert
23005796c8dcSSimon Schubert sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
23015796c8dcSSimon Schubert if (sdata == NULL)
23025796c8dcSSimon Schubert {
23035796c8dcSSimon Schubert sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd,
23045796c8dcSSimon Schubert sizeof (*sdata));
23055796c8dcSSimon Schubert if (sdata == NULL)
23065796c8dcSSimon Schubert return FALSE;
23075796c8dcSSimon Schubert sec->used_by_bfd = sdata;
23085796c8dcSSimon Schubert }
23095796c8dcSSimon Schubert
23105796c8dcSSimon Schubert /* Indicate whether or not this section should use RELA relocations. */
23115796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
23125796c8dcSSimon Schubert sec->use_rela_p = bed->default_use_rela_p;
23135796c8dcSSimon Schubert
23145796c8dcSSimon Schubert /* When we read a file, we don't need to set ELF section type and
23155796c8dcSSimon Schubert flags. They will be overridden in _bfd_elf_make_section_from_shdr
23165796c8dcSSimon Schubert anyway. We will set ELF section type and flags for all linker
23175796c8dcSSimon Schubert created sections. If user specifies BFD section flags, we will
23185796c8dcSSimon Schubert set ELF section type and flags based on BFD section flags in
2319c50c785cSJohn Marino elf_fake_sections. Special handling for .init_array/.fini_array
2320c50c785cSJohn Marino output sections since they may contain .ctors/.dtors input
2321c50c785cSJohn Marino sections. We don't want _bfd_elf_init_private_section_data to
2322c50c785cSJohn Marino copy ELF section type from .ctors/.dtors input sections. */
2323c50c785cSJohn Marino if (abfd->direction != read_direction
23245796c8dcSSimon Schubert || (sec->flags & SEC_LINKER_CREATED) != 0)
23255796c8dcSSimon Schubert {
23265796c8dcSSimon Schubert ssect = (*bed->get_sec_type_attr) (abfd, sec);
2327c50c785cSJohn Marino if (ssect != NULL
2328c50c785cSJohn Marino && (!sec->flags
2329c50c785cSJohn Marino || (sec->flags & SEC_LINKER_CREATED) != 0
2330c50c785cSJohn Marino || ssect->type == SHT_INIT_ARRAY
2331c50c785cSJohn Marino || ssect->type == SHT_FINI_ARRAY))
23325796c8dcSSimon Schubert {
23335796c8dcSSimon Schubert elf_section_type (sec) = ssect->type;
23345796c8dcSSimon Schubert elf_section_flags (sec) = ssect->attr;
23355796c8dcSSimon Schubert }
23365796c8dcSSimon Schubert }
23375796c8dcSSimon Schubert
23385796c8dcSSimon Schubert return _bfd_generic_new_section_hook (abfd, sec);
23395796c8dcSSimon Schubert }
23405796c8dcSSimon Schubert
23415796c8dcSSimon Schubert /* Create a new bfd section from an ELF program header.
23425796c8dcSSimon Schubert
23435796c8dcSSimon Schubert Since program segments have no names, we generate a synthetic name
23445796c8dcSSimon Schubert of the form segment<NUM>, where NUM is generally the index in the
23455796c8dcSSimon Schubert program header table. For segments that are split (see below) we
23465796c8dcSSimon Schubert generate the names segment<NUM>a and segment<NUM>b.
23475796c8dcSSimon Schubert
23485796c8dcSSimon Schubert Note that some program segments may have a file size that is different than
23495796c8dcSSimon Schubert (less than) the memory size. All this means is that at execution the
23505796c8dcSSimon Schubert system must allocate the amount of memory specified by the memory size,
23515796c8dcSSimon Schubert but only initialize it with the first "file size" bytes read from the
23525796c8dcSSimon Schubert file. This would occur for example, with program segments consisting
23535796c8dcSSimon Schubert of combined data+bss.
23545796c8dcSSimon Schubert
23555796c8dcSSimon Schubert To handle the above situation, this routine generates TWO bfd sections
23565796c8dcSSimon Schubert for the single program segment. The first has the length specified by
23575796c8dcSSimon Schubert the file size of the segment, and the second has the length specified
23585796c8dcSSimon Schubert by the difference between the two sizes. In effect, the segment is split
23595796c8dcSSimon Schubert into its initialized and uninitialized parts.
23605796c8dcSSimon Schubert
23615796c8dcSSimon Schubert */
23625796c8dcSSimon Schubert
23635796c8dcSSimon Schubert bfd_boolean
_bfd_elf_make_section_from_phdr(bfd * abfd,Elf_Internal_Phdr * hdr,int hdr_index,const char * type_name)23645796c8dcSSimon Schubert _bfd_elf_make_section_from_phdr (bfd *abfd,
23655796c8dcSSimon Schubert Elf_Internal_Phdr *hdr,
2366cf7f2e2dSJohn Marino int hdr_index,
23675796c8dcSSimon Schubert const char *type_name)
23685796c8dcSSimon Schubert {
23695796c8dcSSimon Schubert asection *newsect;
23705796c8dcSSimon Schubert char *name;
23715796c8dcSSimon Schubert char namebuf[64];
23725796c8dcSSimon Schubert size_t len;
23735796c8dcSSimon Schubert int split;
23745796c8dcSSimon Schubert
23755796c8dcSSimon Schubert split = ((hdr->p_memsz > 0)
23765796c8dcSSimon Schubert && (hdr->p_filesz > 0)
23775796c8dcSSimon Schubert && (hdr->p_memsz > hdr->p_filesz));
23785796c8dcSSimon Schubert
23795796c8dcSSimon Schubert if (hdr->p_filesz > 0)
23805796c8dcSSimon Schubert {
2381cf7f2e2dSJohn Marino sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : "");
23825796c8dcSSimon Schubert len = strlen (namebuf) + 1;
23835796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, len);
23845796c8dcSSimon Schubert if (!name)
23855796c8dcSSimon Schubert return FALSE;
23865796c8dcSSimon Schubert memcpy (name, namebuf, len);
23875796c8dcSSimon Schubert newsect = bfd_make_section (abfd, name);
23885796c8dcSSimon Schubert if (newsect == NULL)
23895796c8dcSSimon Schubert return FALSE;
23905796c8dcSSimon Schubert newsect->vma = hdr->p_vaddr;
23915796c8dcSSimon Schubert newsect->lma = hdr->p_paddr;
23925796c8dcSSimon Schubert newsect->size = hdr->p_filesz;
23935796c8dcSSimon Schubert newsect->filepos = hdr->p_offset;
23945796c8dcSSimon Schubert newsect->flags |= SEC_HAS_CONTENTS;
23955796c8dcSSimon Schubert newsect->alignment_power = bfd_log2 (hdr->p_align);
23965796c8dcSSimon Schubert if (hdr->p_type == PT_LOAD)
23975796c8dcSSimon Schubert {
23985796c8dcSSimon Schubert newsect->flags |= SEC_ALLOC;
23995796c8dcSSimon Schubert newsect->flags |= SEC_LOAD;
24005796c8dcSSimon Schubert if (hdr->p_flags & PF_X)
24015796c8dcSSimon Schubert {
24025796c8dcSSimon Schubert /* FIXME: all we known is that it has execute PERMISSION,
24035796c8dcSSimon Schubert may be data. */
24045796c8dcSSimon Schubert newsect->flags |= SEC_CODE;
24055796c8dcSSimon Schubert }
24065796c8dcSSimon Schubert }
24075796c8dcSSimon Schubert if (!(hdr->p_flags & PF_W))
24085796c8dcSSimon Schubert {
24095796c8dcSSimon Schubert newsect->flags |= SEC_READONLY;
24105796c8dcSSimon Schubert }
24115796c8dcSSimon Schubert }
24125796c8dcSSimon Schubert
24135796c8dcSSimon Schubert if (hdr->p_memsz > hdr->p_filesz)
24145796c8dcSSimon Schubert {
24155796c8dcSSimon Schubert bfd_vma align;
24165796c8dcSSimon Schubert
2417cf7f2e2dSJohn Marino sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : "");
24185796c8dcSSimon Schubert len = strlen (namebuf) + 1;
24195796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, len);
24205796c8dcSSimon Schubert if (!name)
24215796c8dcSSimon Schubert return FALSE;
24225796c8dcSSimon Schubert memcpy (name, namebuf, len);
24235796c8dcSSimon Schubert newsect = bfd_make_section (abfd, name);
24245796c8dcSSimon Schubert if (newsect == NULL)
24255796c8dcSSimon Schubert return FALSE;
24265796c8dcSSimon Schubert newsect->vma = hdr->p_vaddr + hdr->p_filesz;
24275796c8dcSSimon Schubert newsect->lma = hdr->p_paddr + hdr->p_filesz;
24285796c8dcSSimon Schubert newsect->size = hdr->p_memsz - hdr->p_filesz;
24295796c8dcSSimon Schubert newsect->filepos = hdr->p_offset + hdr->p_filesz;
24305796c8dcSSimon Schubert align = newsect->vma & -newsect->vma;
24315796c8dcSSimon Schubert if (align == 0 || align > hdr->p_align)
24325796c8dcSSimon Schubert align = hdr->p_align;
24335796c8dcSSimon Schubert newsect->alignment_power = bfd_log2 (align);
24345796c8dcSSimon Schubert if (hdr->p_type == PT_LOAD)
24355796c8dcSSimon Schubert {
24365796c8dcSSimon Schubert /* Hack for gdb. Segments that have not been modified do
24375796c8dcSSimon Schubert not have their contents written to a core file, on the
24385796c8dcSSimon Schubert assumption that a debugger can find the contents in the
24395796c8dcSSimon Schubert executable. We flag this case by setting the fake
24405796c8dcSSimon Schubert section size to zero. Note that "real" bss sections will
24415796c8dcSSimon Schubert always have their contents dumped to the core file. */
24425796c8dcSSimon Schubert if (bfd_get_format (abfd) == bfd_core)
24435796c8dcSSimon Schubert newsect->size = 0;
24445796c8dcSSimon Schubert newsect->flags |= SEC_ALLOC;
24455796c8dcSSimon Schubert if (hdr->p_flags & PF_X)
24465796c8dcSSimon Schubert newsect->flags |= SEC_CODE;
24475796c8dcSSimon Schubert }
24485796c8dcSSimon Schubert if (!(hdr->p_flags & PF_W))
24495796c8dcSSimon Schubert newsect->flags |= SEC_READONLY;
24505796c8dcSSimon Schubert }
24515796c8dcSSimon Schubert
24525796c8dcSSimon Schubert return TRUE;
24535796c8dcSSimon Schubert }
24545796c8dcSSimon Schubert
24555796c8dcSSimon Schubert bfd_boolean
bfd_section_from_phdr(bfd * abfd,Elf_Internal_Phdr * hdr,int hdr_index)2456cf7f2e2dSJohn Marino bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
24575796c8dcSSimon Schubert {
24585796c8dcSSimon Schubert const struct elf_backend_data *bed;
24595796c8dcSSimon Schubert
24605796c8dcSSimon Schubert switch (hdr->p_type)
24615796c8dcSSimon Schubert {
24625796c8dcSSimon Schubert case PT_NULL:
2463cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null");
24645796c8dcSSimon Schubert
24655796c8dcSSimon Schubert case PT_LOAD:
2466cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load");
24675796c8dcSSimon Schubert
24685796c8dcSSimon Schubert case PT_DYNAMIC:
2469cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic");
24705796c8dcSSimon Schubert
24715796c8dcSSimon Schubert case PT_INTERP:
2472cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp");
24735796c8dcSSimon Schubert
24745796c8dcSSimon Schubert case PT_NOTE:
2475cf7f2e2dSJohn Marino if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
24765796c8dcSSimon Schubert return FALSE;
24775796c8dcSSimon Schubert if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
24785796c8dcSSimon Schubert return FALSE;
24795796c8dcSSimon Schubert return TRUE;
24805796c8dcSSimon Schubert
24815796c8dcSSimon Schubert case PT_SHLIB:
2482cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib");
24835796c8dcSSimon Schubert
24845796c8dcSSimon Schubert case PT_PHDR:
2485cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr");
24865796c8dcSSimon Schubert
24875796c8dcSSimon Schubert case PT_GNU_EH_FRAME:
2488cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
24895796c8dcSSimon Schubert "eh_frame_hdr");
24905796c8dcSSimon Schubert
24915796c8dcSSimon Schubert case PT_GNU_STACK:
2492cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack");
24935796c8dcSSimon Schubert
24945796c8dcSSimon Schubert case PT_GNU_RELRO:
2495cf7f2e2dSJohn Marino return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro");
24965796c8dcSSimon Schubert
24975796c8dcSSimon Schubert default:
24985796c8dcSSimon Schubert /* Check for any processor-specific program segment types. */
24995796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
2500cf7f2e2dSJohn Marino return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc");
25015796c8dcSSimon Schubert }
25025796c8dcSSimon Schubert }
25035796c8dcSSimon Schubert
2504c50c785cSJohn Marino /* Return the REL_HDR for SEC, assuming there is only a single one, either
2505c50c785cSJohn Marino REL or RELA. */
2506c50c785cSJohn Marino
2507c50c785cSJohn Marino Elf_Internal_Shdr *
_bfd_elf_single_rel_hdr(asection * sec)2508c50c785cSJohn Marino _bfd_elf_single_rel_hdr (asection *sec)
2509c50c785cSJohn Marino {
2510c50c785cSJohn Marino if (elf_section_data (sec)->rel.hdr)
2511c50c785cSJohn Marino {
2512c50c785cSJohn Marino BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
2513c50c785cSJohn Marino return elf_section_data (sec)->rel.hdr;
2514c50c785cSJohn Marino }
2515c50c785cSJohn Marino else
2516c50c785cSJohn Marino return elf_section_data (sec)->rela.hdr;
2517c50c785cSJohn Marino }
2518c50c785cSJohn Marino
2519c50c785cSJohn Marino /* Allocate and initialize a section-header for a new reloc section,
2520c50c785cSJohn Marino containing relocations against ASECT. It is stored in RELDATA. If
2521c50c785cSJohn Marino USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
2522c50c785cSJohn Marino relocations. */
25235796c8dcSSimon Schubert
25245796c8dcSSimon Schubert bfd_boolean
_bfd_elf_init_reloc_shdr(bfd * abfd,struct bfd_elf_section_reloc_data * reldata,asection * asect,bfd_boolean use_rela_p)25255796c8dcSSimon Schubert _bfd_elf_init_reloc_shdr (bfd *abfd,
2526c50c785cSJohn Marino struct bfd_elf_section_reloc_data *reldata,
25275796c8dcSSimon Schubert asection *asect,
25285796c8dcSSimon Schubert bfd_boolean use_rela_p)
25295796c8dcSSimon Schubert {
2530c50c785cSJohn Marino Elf_Internal_Shdr *rel_hdr;
25315796c8dcSSimon Schubert char *name;
25325796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2533c50c785cSJohn Marino bfd_size_type amt;
25345796c8dcSSimon Schubert
2535c50c785cSJohn Marino amt = sizeof (Elf_Internal_Shdr);
2536c50c785cSJohn Marino BFD_ASSERT (reldata->hdr == NULL);
2537c50c785cSJohn Marino rel_hdr = bfd_zalloc (abfd, amt);
2538c50c785cSJohn Marino reldata->hdr = rel_hdr;
2539c50c785cSJohn Marino
2540c50c785cSJohn Marino amt = sizeof ".rela" + strlen (asect->name);
25415796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, amt);
25425796c8dcSSimon Schubert if (name == NULL)
25435796c8dcSSimon Schubert return FALSE;
25445796c8dcSSimon Schubert sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
25455796c8dcSSimon Schubert rel_hdr->sh_name =
25465796c8dcSSimon Schubert (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
25475796c8dcSSimon Schubert FALSE);
25485796c8dcSSimon Schubert if (rel_hdr->sh_name == (unsigned int) -1)
25495796c8dcSSimon Schubert return FALSE;
25505796c8dcSSimon Schubert rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
25515796c8dcSSimon Schubert rel_hdr->sh_entsize = (use_rela_p
25525796c8dcSSimon Schubert ? bed->s->sizeof_rela
25535796c8dcSSimon Schubert : bed->s->sizeof_rel);
25545796c8dcSSimon Schubert rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
25555796c8dcSSimon Schubert rel_hdr->sh_flags = 0;
25565796c8dcSSimon Schubert rel_hdr->sh_addr = 0;
25575796c8dcSSimon Schubert rel_hdr->sh_size = 0;
25585796c8dcSSimon Schubert rel_hdr->sh_offset = 0;
25595796c8dcSSimon Schubert
25605796c8dcSSimon Schubert return TRUE;
25615796c8dcSSimon Schubert }
25625796c8dcSSimon Schubert
25635796c8dcSSimon Schubert /* Return the default section type based on the passed in section flags. */
25645796c8dcSSimon Schubert
25655796c8dcSSimon Schubert int
bfd_elf_get_default_section_type(flagword flags)25665796c8dcSSimon Schubert bfd_elf_get_default_section_type (flagword flags)
25675796c8dcSSimon Schubert {
25685796c8dcSSimon Schubert if ((flags & SEC_ALLOC) != 0
2569c50c785cSJohn Marino && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
25705796c8dcSSimon Schubert return SHT_NOBITS;
25715796c8dcSSimon Schubert return SHT_PROGBITS;
25725796c8dcSSimon Schubert }
25735796c8dcSSimon Schubert
2574c50c785cSJohn Marino struct fake_section_arg
2575c50c785cSJohn Marino {
2576c50c785cSJohn Marino struct bfd_link_info *link_info;
2577c50c785cSJohn Marino bfd_boolean failed;
2578c50c785cSJohn Marino };
2579c50c785cSJohn Marino
25805796c8dcSSimon Schubert /* Set up an ELF internal section header for a section. */
25815796c8dcSSimon Schubert
25825796c8dcSSimon Schubert static void
elf_fake_sections(bfd * abfd,asection * asect,void * fsarg)2583c50c785cSJohn Marino elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
25845796c8dcSSimon Schubert {
2585c50c785cSJohn Marino struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
25865796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2587c50c785cSJohn Marino struct bfd_elf_section_data *esd = elf_section_data (asect);
25885796c8dcSSimon Schubert Elf_Internal_Shdr *this_hdr;
25895796c8dcSSimon Schubert unsigned int sh_type;
25905796c8dcSSimon Schubert
2591c50c785cSJohn Marino if (arg->failed)
25925796c8dcSSimon Schubert {
25935796c8dcSSimon Schubert /* We already failed; just get out of the bfd_map_over_sections
25945796c8dcSSimon Schubert loop. */
25955796c8dcSSimon Schubert return;
25965796c8dcSSimon Schubert }
25975796c8dcSSimon Schubert
2598c50c785cSJohn Marino this_hdr = &esd->this_hdr;
25995796c8dcSSimon Schubert
26005796c8dcSSimon Schubert this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
26015796c8dcSSimon Schubert asect->name, FALSE);
26025796c8dcSSimon Schubert if (this_hdr->sh_name == (unsigned int) -1)
26035796c8dcSSimon Schubert {
2604c50c785cSJohn Marino arg->failed = TRUE;
26055796c8dcSSimon Schubert return;
26065796c8dcSSimon Schubert }
26075796c8dcSSimon Schubert
26085796c8dcSSimon Schubert /* Don't clear sh_flags. Assembler may set additional bits. */
26095796c8dcSSimon Schubert
26105796c8dcSSimon Schubert if ((asect->flags & SEC_ALLOC) != 0
26115796c8dcSSimon Schubert || asect->user_set_vma)
26125796c8dcSSimon Schubert this_hdr->sh_addr = asect->vma;
26135796c8dcSSimon Schubert else
26145796c8dcSSimon Schubert this_hdr->sh_addr = 0;
26155796c8dcSSimon Schubert
26165796c8dcSSimon Schubert this_hdr->sh_offset = 0;
26175796c8dcSSimon Schubert this_hdr->sh_size = asect->size;
26185796c8dcSSimon Schubert this_hdr->sh_link = 0;
26195796c8dcSSimon Schubert this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power;
26205796c8dcSSimon Schubert /* The sh_entsize and sh_info fields may have been set already by
26215796c8dcSSimon Schubert copy_private_section_data. */
26225796c8dcSSimon Schubert
26235796c8dcSSimon Schubert this_hdr->bfd_section = asect;
26245796c8dcSSimon Schubert this_hdr->contents = NULL;
26255796c8dcSSimon Schubert
26265796c8dcSSimon Schubert /* If the section type is unspecified, we set it based on
26275796c8dcSSimon Schubert asect->flags. */
26285796c8dcSSimon Schubert if ((asect->flags & SEC_GROUP) != 0)
26295796c8dcSSimon Schubert sh_type = SHT_GROUP;
26305796c8dcSSimon Schubert else
26315796c8dcSSimon Schubert sh_type = bfd_elf_get_default_section_type (asect->flags);
26325796c8dcSSimon Schubert
26335796c8dcSSimon Schubert if (this_hdr->sh_type == SHT_NULL)
26345796c8dcSSimon Schubert this_hdr->sh_type = sh_type;
26355796c8dcSSimon Schubert else if (this_hdr->sh_type == SHT_NOBITS
26365796c8dcSSimon Schubert && sh_type == SHT_PROGBITS
26375796c8dcSSimon Schubert && (asect->flags & SEC_ALLOC) != 0)
26385796c8dcSSimon Schubert {
26395796c8dcSSimon Schubert /* Warn if we are changing a NOBITS section to PROGBITS, but
26405796c8dcSSimon Schubert allow the link to proceed. This can happen when users link
26415796c8dcSSimon Schubert non-bss input sections to bss output sections, or emit data
26425796c8dcSSimon Schubert to a bss output section via a linker script. */
26435796c8dcSSimon Schubert (*_bfd_error_handler)
26445796c8dcSSimon Schubert (_("warning: section `%A' type changed to PROGBITS"), asect);
26455796c8dcSSimon Schubert this_hdr->sh_type = sh_type;
26465796c8dcSSimon Schubert }
26475796c8dcSSimon Schubert
26485796c8dcSSimon Schubert switch (this_hdr->sh_type)
26495796c8dcSSimon Schubert {
26505796c8dcSSimon Schubert default:
26515796c8dcSSimon Schubert break;
26525796c8dcSSimon Schubert
26535796c8dcSSimon Schubert case SHT_STRTAB:
26545796c8dcSSimon Schubert case SHT_INIT_ARRAY:
26555796c8dcSSimon Schubert case SHT_FINI_ARRAY:
26565796c8dcSSimon Schubert case SHT_PREINIT_ARRAY:
26575796c8dcSSimon Schubert case SHT_NOTE:
26585796c8dcSSimon Schubert case SHT_NOBITS:
26595796c8dcSSimon Schubert case SHT_PROGBITS:
26605796c8dcSSimon Schubert break;
26615796c8dcSSimon Schubert
26625796c8dcSSimon Schubert case SHT_HASH:
26635796c8dcSSimon Schubert this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
26645796c8dcSSimon Schubert break;
26655796c8dcSSimon Schubert
26665796c8dcSSimon Schubert case SHT_DYNSYM:
26675796c8dcSSimon Schubert this_hdr->sh_entsize = bed->s->sizeof_sym;
26685796c8dcSSimon Schubert break;
26695796c8dcSSimon Schubert
26705796c8dcSSimon Schubert case SHT_DYNAMIC:
26715796c8dcSSimon Schubert this_hdr->sh_entsize = bed->s->sizeof_dyn;
26725796c8dcSSimon Schubert break;
26735796c8dcSSimon Schubert
26745796c8dcSSimon Schubert case SHT_RELA:
26755796c8dcSSimon Schubert if (get_elf_backend_data (abfd)->may_use_rela_p)
26765796c8dcSSimon Schubert this_hdr->sh_entsize = bed->s->sizeof_rela;
26775796c8dcSSimon Schubert break;
26785796c8dcSSimon Schubert
26795796c8dcSSimon Schubert case SHT_REL:
26805796c8dcSSimon Schubert if (get_elf_backend_data (abfd)->may_use_rel_p)
26815796c8dcSSimon Schubert this_hdr->sh_entsize = bed->s->sizeof_rel;
26825796c8dcSSimon Schubert break;
26835796c8dcSSimon Schubert
26845796c8dcSSimon Schubert case SHT_GNU_versym:
26855796c8dcSSimon Schubert this_hdr->sh_entsize = sizeof (Elf_External_Versym);
26865796c8dcSSimon Schubert break;
26875796c8dcSSimon Schubert
26885796c8dcSSimon Schubert case SHT_GNU_verdef:
26895796c8dcSSimon Schubert this_hdr->sh_entsize = 0;
26905796c8dcSSimon Schubert /* objcopy or strip will copy over sh_info, but may not set
26915796c8dcSSimon Schubert cverdefs. The linker will set cverdefs, but sh_info will be
26925796c8dcSSimon Schubert zero. */
26935796c8dcSSimon Schubert if (this_hdr->sh_info == 0)
26945796c8dcSSimon Schubert this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
26955796c8dcSSimon Schubert else
26965796c8dcSSimon Schubert BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
26975796c8dcSSimon Schubert || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
26985796c8dcSSimon Schubert break;
26995796c8dcSSimon Schubert
27005796c8dcSSimon Schubert case SHT_GNU_verneed:
27015796c8dcSSimon Schubert this_hdr->sh_entsize = 0;
27025796c8dcSSimon Schubert /* objcopy or strip will copy over sh_info, but may not set
27035796c8dcSSimon Schubert cverrefs. The linker will set cverrefs, but sh_info will be
27045796c8dcSSimon Schubert zero. */
27055796c8dcSSimon Schubert if (this_hdr->sh_info == 0)
27065796c8dcSSimon Schubert this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
27075796c8dcSSimon Schubert else
27085796c8dcSSimon Schubert BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
27095796c8dcSSimon Schubert || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
27105796c8dcSSimon Schubert break;
27115796c8dcSSimon Schubert
27125796c8dcSSimon Schubert case SHT_GROUP:
27135796c8dcSSimon Schubert this_hdr->sh_entsize = GRP_ENTRY_SIZE;
27145796c8dcSSimon Schubert break;
27155796c8dcSSimon Schubert
27165796c8dcSSimon Schubert case SHT_GNU_HASH:
27175796c8dcSSimon Schubert this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
27185796c8dcSSimon Schubert break;
27195796c8dcSSimon Schubert }
27205796c8dcSSimon Schubert
27215796c8dcSSimon Schubert if ((asect->flags & SEC_ALLOC) != 0)
27225796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_ALLOC;
27235796c8dcSSimon Schubert if ((asect->flags & SEC_READONLY) == 0)
27245796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_WRITE;
27255796c8dcSSimon Schubert if ((asect->flags & SEC_CODE) != 0)
27265796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_EXECINSTR;
27275796c8dcSSimon Schubert if ((asect->flags & SEC_MERGE) != 0)
27285796c8dcSSimon Schubert {
27295796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_MERGE;
27305796c8dcSSimon Schubert this_hdr->sh_entsize = asect->entsize;
27315796c8dcSSimon Schubert if ((asect->flags & SEC_STRINGS) != 0)
27325796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_STRINGS;
27335796c8dcSSimon Schubert }
27345796c8dcSSimon Schubert if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
27355796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_GROUP;
27365796c8dcSSimon Schubert if ((asect->flags & SEC_THREAD_LOCAL) != 0)
27375796c8dcSSimon Schubert {
27385796c8dcSSimon Schubert this_hdr->sh_flags |= SHF_TLS;
27395796c8dcSSimon Schubert if (asect->size == 0
27405796c8dcSSimon Schubert && (asect->flags & SEC_HAS_CONTENTS) == 0)
27415796c8dcSSimon Schubert {
27425796c8dcSSimon Schubert struct bfd_link_order *o = asect->map_tail.link_order;
27435796c8dcSSimon Schubert
27445796c8dcSSimon Schubert this_hdr->sh_size = 0;
27455796c8dcSSimon Schubert if (o != NULL)
27465796c8dcSSimon Schubert {
27475796c8dcSSimon Schubert this_hdr->sh_size = o->offset + o->size;
27485796c8dcSSimon Schubert if (this_hdr->sh_size != 0)
27495796c8dcSSimon Schubert this_hdr->sh_type = SHT_NOBITS;
27505796c8dcSSimon Schubert }
27515796c8dcSSimon Schubert }
27525796c8dcSSimon Schubert }
2753cf7f2e2dSJohn Marino if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
2754cf7f2e2dSJohn Marino this_hdr->sh_flags |= SHF_EXCLUDE;
27555796c8dcSSimon Schubert
2756c50c785cSJohn Marino /* If the section has relocs, set up a section header for the
2757c50c785cSJohn Marino SHT_REL[A] section. If two relocation sections are required for
2758c50c785cSJohn Marino this section, it is up to the processor-specific back-end to
2759c50c785cSJohn Marino create the other. */
2760c50c785cSJohn Marino if ((asect->flags & SEC_RELOC) != 0)
2761c50c785cSJohn Marino {
2762c50c785cSJohn Marino /* When doing a relocatable link, create both REL and RELA sections if
2763c50c785cSJohn Marino needed. */
2764c50c785cSJohn Marino if (arg->link_info
2765c50c785cSJohn Marino /* Do the normal setup if we wouldn't create any sections here. */
2766c50c785cSJohn Marino && esd->rel.count + esd->rela.count > 0
2767c50c785cSJohn Marino && (arg->link_info->relocatable || arg->link_info->emitrelocations))
2768c50c785cSJohn Marino {
2769c50c785cSJohn Marino if (esd->rel.count && esd->rel.hdr == NULL
2770c50c785cSJohn Marino && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
2771c50c785cSJohn Marino {
2772c50c785cSJohn Marino arg->failed = TRUE;
2773c50c785cSJohn Marino return;
2774c50c785cSJohn Marino }
2775c50c785cSJohn Marino if (esd->rela.count && esd->rela.hdr == NULL
2776c50c785cSJohn Marino && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
2777c50c785cSJohn Marino {
2778c50c785cSJohn Marino arg->failed = TRUE;
2779c50c785cSJohn Marino return;
2780c50c785cSJohn Marino }
2781c50c785cSJohn Marino }
2782c50c785cSJohn Marino else if (!_bfd_elf_init_reloc_shdr (abfd,
2783c50c785cSJohn Marino (asect->use_rela_p
2784c50c785cSJohn Marino ? &esd->rela : &esd->rel),
2785c50c785cSJohn Marino asect,
2786c50c785cSJohn Marino asect->use_rela_p))
2787c50c785cSJohn Marino arg->failed = TRUE;
2788c50c785cSJohn Marino }
2789c50c785cSJohn Marino
27905796c8dcSSimon Schubert /* Check for processor-specific section types. */
27915796c8dcSSimon Schubert sh_type = this_hdr->sh_type;
27925796c8dcSSimon Schubert if (bed->elf_backend_fake_sections
27935796c8dcSSimon Schubert && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
2794c50c785cSJohn Marino arg->failed = TRUE;
27955796c8dcSSimon Schubert
27965796c8dcSSimon Schubert if (sh_type == SHT_NOBITS && asect->size != 0)
27975796c8dcSSimon Schubert {
27985796c8dcSSimon Schubert /* Don't change the header type from NOBITS if we are being
27995796c8dcSSimon Schubert called for objcopy --only-keep-debug. */
28005796c8dcSSimon Schubert this_hdr->sh_type = sh_type;
28015796c8dcSSimon Schubert }
28025796c8dcSSimon Schubert }
28035796c8dcSSimon Schubert
28045796c8dcSSimon Schubert /* Fill in the contents of a SHT_GROUP section. Called from
28055796c8dcSSimon Schubert _bfd_elf_compute_section_file_positions for gas, objcopy, and
28065796c8dcSSimon Schubert when ELF targets use the generic linker, ld. Called for ld -r
28075796c8dcSSimon Schubert from bfd_elf_final_link. */
28085796c8dcSSimon Schubert
28095796c8dcSSimon Schubert void
bfd_elf_set_group_contents(bfd * abfd,asection * sec,void * failedptrarg)28105796c8dcSSimon Schubert bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
28115796c8dcSSimon Schubert {
28125796c8dcSSimon Schubert bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
28135796c8dcSSimon Schubert asection *elt, *first;
28145796c8dcSSimon Schubert unsigned char *loc;
28155796c8dcSSimon Schubert bfd_boolean gas;
28165796c8dcSSimon Schubert
28175796c8dcSSimon Schubert /* Ignore linker created group section. See elfNN_ia64_object_p in
28185796c8dcSSimon Schubert elfxx-ia64.c. */
28195796c8dcSSimon Schubert if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
28205796c8dcSSimon Schubert || *failedptr)
28215796c8dcSSimon Schubert return;
28225796c8dcSSimon Schubert
28235796c8dcSSimon Schubert if (elf_section_data (sec)->this_hdr.sh_info == 0)
28245796c8dcSSimon Schubert {
28255796c8dcSSimon Schubert unsigned long symindx = 0;
28265796c8dcSSimon Schubert
28275796c8dcSSimon Schubert /* elf_group_id will have been set up by objcopy and the
28285796c8dcSSimon Schubert generic linker. */
28295796c8dcSSimon Schubert if (elf_group_id (sec) != NULL)
28305796c8dcSSimon Schubert symindx = elf_group_id (sec)->udata.i;
28315796c8dcSSimon Schubert
28325796c8dcSSimon Schubert if (symindx == 0)
28335796c8dcSSimon Schubert {
28345796c8dcSSimon Schubert /* If called from the assembler, swap_out_syms will have set up
28355796c8dcSSimon Schubert elf_section_syms. */
28365796c8dcSSimon Schubert BFD_ASSERT (elf_section_syms (abfd) != NULL);
28375796c8dcSSimon Schubert symindx = elf_section_syms (abfd)[sec->index]->udata.i;
28385796c8dcSSimon Schubert }
28395796c8dcSSimon Schubert elf_section_data (sec)->this_hdr.sh_info = symindx;
28405796c8dcSSimon Schubert }
28415796c8dcSSimon Schubert else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
28425796c8dcSSimon Schubert {
28435796c8dcSSimon Schubert /* The ELF backend linker sets sh_info to -2 when the group
28445796c8dcSSimon Schubert signature symbol is global, and thus the index can't be
28455796c8dcSSimon Schubert set until all local symbols are output. */
28465796c8dcSSimon Schubert asection *igroup = elf_sec_group (elf_next_in_group (sec));
28475796c8dcSSimon Schubert struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
28485796c8dcSSimon Schubert unsigned long symndx = sec_data->this_hdr.sh_info;
28495796c8dcSSimon Schubert unsigned long extsymoff = 0;
28505796c8dcSSimon Schubert struct elf_link_hash_entry *h;
28515796c8dcSSimon Schubert
28525796c8dcSSimon Schubert if (!elf_bad_symtab (igroup->owner))
28535796c8dcSSimon Schubert {
28545796c8dcSSimon Schubert Elf_Internal_Shdr *symtab_hdr;
28555796c8dcSSimon Schubert
28565796c8dcSSimon Schubert symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
28575796c8dcSSimon Schubert extsymoff = symtab_hdr->sh_info;
28585796c8dcSSimon Schubert }
28595796c8dcSSimon Schubert h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
28605796c8dcSSimon Schubert while (h->root.type == bfd_link_hash_indirect
28615796c8dcSSimon Schubert || h->root.type == bfd_link_hash_warning)
28625796c8dcSSimon Schubert h = (struct elf_link_hash_entry *) h->root.u.i.link;
28635796c8dcSSimon Schubert
28645796c8dcSSimon Schubert elf_section_data (sec)->this_hdr.sh_info = h->indx;
28655796c8dcSSimon Schubert }
28665796c8dcSSimon Schubert
28675796c8dcSSimon Schubert /* The contents won't be allocated for "ld -r" or objcopy. */
28685796c8dcSSimon Schubert gas = TRUE;
28695796c8dcSSimon Schubert if (sec->contents == NULL)
28705796c8dcSSimon Schubert {
28715796c8dcSSimon Schubert gas = FALSE;
28725796c8dcSSimon Schubert sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);
28735796c8dcSSimon Schubert
28745796c8dcSSimon Schubert /* Arrange for the section to be written out. */
28755796c8dcSSimon Schubert elf_section_data (sec)->this_hdr.contents = sec->contents;
28765796c8dcSSimon Schubert if (sec->contents == NULL)
28775796c8dcSSimon Schubert {
28785796c8dcSSimon Schubert *failedptr = TRUE;
28795796c8dcSSimon Schubert return;
28805796c8dcSSimon Schubert }
28815796c8dcSSimon Schubert }
28825796c8dcSSimon Schubert
28835796c8dcSSimon Schubert loc = sec->contents + sec->size;
28845796c8dcSSimon Schubert
28855796c8dcSSimon Schubert /* Get the pointer to the first section in the group that gas
28865796c8dcSSimon Schubert squirreled away here. objcopy arranges for this to be set to the
28875796c8dcSSimon Schubert start of the input section group. */
28885796c8dcSSimon Schubert first = elt = elf_next_in_group (sec);
28895796c8dcSSimon Schubert
28905796c8dcSSimon Schubert /* First element is a flag word. Rest of section is elf section
28915796c8dcSSimon Schubert indices for all the sections of the group. Write them backwards
28925796c8dcSSimon Schubert just to keep the group in the same order as given in .section
28935796c8dcSSimon Schubert directives, not that it matters. */
28945796c8dcSSimon Schubert while (elt != NULL)
28955796c8dcSSimon Schubert {
28965796c8dcSSimon Schubert asection *s;
28975796c8dcSSimon Schubert
28985796c8dcSSimon Schubert s = elt;
28995796c8dcSSimon Schubert if (!gas)
29005796c8dcSSimon Schubert s = s->output_section;
2901cf7f2e2dSJohn Marino if (s != NULL
2902cf7f2e2dSJohn Marino && !bfd_is_abs_section (s))
2903cf7f2e2dSJohn Marino {
2904cf7f2e2dSJohn Marino unsigned int idx = elf_section_data (s)->this_idx;
2905cf7f2e2dSJohn Marino
2906cf7f2e2dSJohn Marino loc -= 4;
29075796c8dcSSimon Schubert H_PUT_32 (abfd, idx, loc);
29085796c8dcSSimon Schubert }
29095796c8dcSSimon Schubert elt = elf_next_in_group (elt);
29105796c8dcSSimon Schubert if (elt == first)
29115796c8dcSSimon Schubert break;
29125796c8dcSSimon Schubert }
29135796c8dcSSimon Schubert
29145796c8dcSSimon Schubert if ((loc -= 4) != sec->contents)
29155796c8dcSSimon Schubert abort ();
29165796c8dcSSimon Schubert
29175796c8dcSSimon Schubert H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
29185796c8dcSSimon Schubert }
29195796c8dcSSimon Schubert
29205796c8dcSSimon Schubert /* Assign all ELF section numbers. The dummy first section is handled here
29215796c8dcSSimon Schubert too. The link/info pointers for the standard section types are filled
29225796c8dcSSimon Schubert in here too, while we're at it. */
29235796c8dcSSimon Schubert
29245796c8dcSSimon Schubert static bfd_boolean
assign_section_numbers(bfd * abfd,struct bfd_link_info * link_info)29255796c8dcSSimon Schubert assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
29265796c8dcSSimon Schubert {
29275796c8dcSSimon Schubert struct elf_obj_tdata *t = elf_tdata (abfd);
29285796c8dcSSimon Schubert asection *sec;
29295796c8dcSSimon Schubert unsigned int section_number, secn;
29305796c8dcSSimon Schubert Elf_Internal_Shdr **i_shdrp;
29315796c8dcSSimon Schubert struct bfd_elf_section_data *d;
29325796c8dcSSimon Schubert bfd_boolean need_symtab;
29335796c8dcSSimon Schubert
29345796c8dcSSimon Schubert section_number = 1;
29355796c8dcSSimon Schubert
29365796c8dcSSimon Schubert _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
29375796c8dcSSimon Schubert
29385796c8dcSSimon Schubert /* SHT_GROUP sections are in relocatable files only. */
29395796c8dcSSimon Schubert if (link_info == NULL || link_info->relocatable)
29405796c8dcSSimon Schubert {
29415796c8dcSSimon Schubert /* Put SHT_GROUP sections first. */
29425796c8dcSSimon Schubert for (sec = abfd->sections; sec != NULL; sec = sec->next)
29435796c8dcSSimon Schubert {
29445796c8dcSSimon Schubert d = elf_section_data (sec);
29455796c8dcSSimon Schubert
29465796c8dcSSimon Schubert if (d->this_hdr.sh_type == SHT_GROUP)
29475796c8dcSSimon Schubert {
29485796c8dcSSimon Schubert if (sec->flags & SEC_LINKER_CREATED)
29495796c8dcSSimon Schubert {
29505796c8dcSSimon Schubert /* Remove the linker created SHT_GROUP sections. */
29515796c8dcSSimon Schubert bfd_section_list_remove (abfd, sec);
29525796c8dcSSimon Schubert abfd->section_count--;
29535796c8dcSSimon Schubert }
29545796c8dcSSimon Schubert else
29555796c8dcSSimon Schubert d->this_idx = section_number++;
29565796c8dcSSimon Schubert }
29575796c8dcSSimon Schubert }
29585796c8dcSSimon Schubert }
29595796c8dcSSimon Schubert
29605796c8dcSSimon Schubert for (sec = abfd->sections; sec; sec = sec->next)
29615796c8dcSSimon Schubert {
29625796c8dcSSimon Schubert d = elf_section_data (sec);
29635796c8dcSSimon Schubert
29645796c8dcSSimon Schubert if (d->this_hdr.sh_type != SHT_GROUP)
29655796c8dcSSimon Schubert d->this_idx = section_number++;
29665796c8dcSSimon Schubert _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
2967c50c785cSJohn Marino if (d->rel.hdr)
29685796c8dcSSimon Schubert {
2969c50c785cSJohn Marino d->rel.idx = section_number++;
2970c50c785cSJohn Marino _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
29715796c8dcSSimon Schubert }
2972c50c785cSJohn Marino else
2973c50c785cSJohn Marino d->rel.idx = 0;
29745796c8dcSSimon Schubert
2975c50c785cSJohn Marino if (d->rela.hdr)
29765796c8dcSSimon Schubert {
2977c50c785cSJohn Marino d->rela.idx = section_number++;
2978c50c785cSJohn Marino _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
29795796c8dcSSimon Schubert }
29805796c8dcSSimon Schubert else
2981c50c785cSJohn Marino d->rela.idx = 0;
29825796c8dcSSimon Schubert }
29835796c8dcSSimon Schubert
2984*ef5ccd6cSJohn Marino elf_shstrtab_sec (abfd) = section_number++;
29855796c8dcSSimon Schubert _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
2986*ef5ccd6cSJohn Marino elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
29875796c8dcSSimon Schubert
29885796c8dcSSimon Schubert need_symtab = (bfd_get_symcount (abfd) > 0
29895796c8dcSSimon Schubert || (link_info == NULL
29905796c8dcSSimon Schubert && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
29915796c8dcSSimon Schubert == HAS_RELOC)));
29925796c8dcSSimon Schubert if (need_symtab)
29935796c8dcSSimon Schubert {
2994*ef5ccd6cSJohn Marino elf_onesymtab (abfd) = section_number++;
29955796c8dcSSimon Schubert _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
29965796c8dcSSimon Schubert if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
29975796c8dcSSimon Schubert {
2998*ef5ccd6cSJohn Marino elf_symtab_shndx (abfd) = section_number++;
29995796c8dcSSimon Schubert t->symtab_shndx_hdr.sh_name
30005796c8dcSSimon Schubert = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
30015796c8dcSSimon Schubert ".symtab_shndx", FALSE);
30025796c8dcSSimon Schubert if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
30035796c8dcSSimon Schubert return FALSE;
30045796c8dcSSimon Schubert }
3005*ef5ccd6cSJohn Marino elf_strtab_sec (abfd) = section_number++;
30065796c8dcSSimon Schubert _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
30075796c8dcSSimon Schubert }
30085796c8dcSSimon Schubert
3009*ef5ccd6cSJohn Marino if (section_number >= SHN_LORESERVE)
3010*ef5ccd6cSJohn Marino {
3011*ef5ccd6cSJohn Marino _bfd_error_handler (_("%B: too many sections: %u"),
3012*ef5ccd6cSJohn Marino abfd, section_number);
3013*ef5ccd6cSJohn Marino return FALSE;
3014*ef5ccd6cSJohn Marino }
3015*ef5ccd6cSJohn Marino
30165796c8dcSSimon Schubert _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
30175796c8dcSSimon Schubert t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
30185796c8dcSSimon Schubert
30195796c8dcSSimon Schubert elf_numsections (abfd) = section_number;
30205796c8dcSSimon Schubert elf_elfheader (abfd)->e_shnum = section_number;
30215796c8dcSSimon Schubert
30225796c8dcSSimon Schubert /* Set up the list of section header pointers, in agreement with the
30235796c8dcSSimon Schubert indices. */
30245796c8dcSSimon Schubert i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc2 (abfd, section_number,
30255796c8dcSSimon Schubert sizeof (Elf_Internal_Shdr *));
30265796c8dcSSimon Schubert if (i_shdrp == NULL)
30275796c8dcSSimon Schubert return FALSE;
30285796c8dcSSimon Schubert
30295796c8dcSSimon Schubert i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd,
30305796c8dcSSimon Schubert sizeof (Elf_Internal_Shdr));
30315796c8dcSSimon Schubert if (i_shdrp[0] == NULL)
30325796c8dcSSimon Schubert {
30335796c8dcSSimon Schubert bfd_release (abfd, i_shdrp);
30345796c8dcSSimon Schubert return FALSE;
30355796c8dcSSimon Schubert }
30365796c8dcSSimon Schubert
30375796c8dcSSimon Schubert elf_elfsections (abfd) = i_shdrp;
30385796c8dcSSimon Schubert
3039*ef5ccd6cSJohn Marino i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr;
30405796c8dcSSimon Schubert if (need_symtab)
30415796c8dcSSimon Schubert {
3042*ef5ccd6cSJohn Marino i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
30435796c8dcSSimon Schubert if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
30445796c8dcSSimon Schubert {
3045*ef5ccd6cSJohn Marino i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr;
3046*ef5ccd6cSJohn Marino t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd);
30475796c8dcSSimon Schubert }
3048*ef5ccd6cSJohn Marino i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
3049*ef5ccd6cSJohn Marino t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
30505796c8dcSSimon Schubert }
30515796c8dcSSimon Schubert
30525796c8dcSSimon Schubert for (sec = abfd->sections; sec; sec = sec->next)
30535796c8dcSSimon Schubert {
30545796c8dcSSimon Schubert asection *s;
30555796c8dcSSimon Schubert const char *name;
30565796c8dcSSimon Schubert
3057cf7f2e2dSJohn Marino d = elf_section_data (sec);
3058cf7f2e2dSJohn Marino
30595796c8dcSSimon Schubert i_shdrp[d->this_idx] = &d->this_hdr;
3060c50c785cSJohn Marino if (d->rel.idx != 0)
3061c50c785cSJohn Marino i_shdrp[d->rel.idx] = d->rel.hdr;
3062c50c785cSJohn Marino if (d->rela.idx != 0)
3063c50c785cSJohn Marino i_shdrp[d->rela.idx] = d->rela.hdr;
30645796c8dcSSimon Schubert
30655796c8dcSSimon Schubert /* Fill in the sh_link and sh_info fields while we're at it. */
30665796c8dcSSimon Schubert
30675796c8dcSSimon Schubert /* sh_link of a reloc section is the section index of the symbol
30685796c8dcSSimon Schubert table. sh_info is the section index of the section to which
30695796c8dcSSimon Schubert the relocation entries apply. */
3070c50c785cSJohn Marino if (d->rel.idx != 0)
30715796c8dcSSimon Schubert {
3072*ef5ccd6cSJohn Marino d->rel.hdr->sh_link = elf_onesymtab (abfd);
3073c50c785cSJohn Marino d->rel.hdr->sh_info = d->this_idx;
30745796c8dcSSimon Schubert }
3075c50c785cSJohn Marino if (d->rela.idx != 0)
30765796c8dcSSimon Schubert {
3077*ef5ccd6cSJohn Marino d->rela.hdr->sh_link = elf_onesymtab (abfd);
3078c50c785cSJohn Marino d->rela.hdr->sh_info = d->this_idx;
30795796c8dcSSimon Schubert }
30805796c8dcSSimon Schubert
30815796c8dcSSimon Schubert /* We need to set up sh_link for SHF_LINK_ORDER. */
30825796c8dcSSimon Schubert if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
30835796c8dcSSimon Schubert {
30845796c8dcSSimon Schubert s = elf_linked_to_section (sec);
30855796c8dcSSimon Schubert if (s)
30865796c8dcSSimon Schubert {
30875796c8dcSSimon Schubert /* elf_linked_to_section points to the input section. */
30885796c8dcSSimon Schubert if (link_info != NULL)
30895796c8dcSSimon Schubert {
30905796c8dcSSimon Schubert /* Check discarded linkonce section. */
3091*ef5ccd6cSJohn Marino if (discarded_section (s))
30925796c8dcSSimon Schubert {
30935796c8dcSSimon Schubert asection *kept;
30945796c8dcSSimon Schubert (*_bfd_error_handler)
30955796c8dcSSimon Schubert (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
30965796c8dcSSimon Schubert abfd, d->this_hdr.bfd_section,
30975796c8dcSSimon Schubert s, s->owner);
30985796c8dcSSimon Schubert /* Point to the kept section if it has the same
30995796c8dcSSimon Schubert size as the discarded one. */
31005796c8dcSSimon Schubert kept = _bfd_elf_check_kept_section (s, link_info);
31015796c8dcSSimon Schubert if (kept == NULL)
31025796c8dcSSimon Schubert {
31035796c8dcSSimon Schubert bfd_set_error (bfd_error_bad_value);
31045796c8dcSSimon Schubert return FALSE;
31055796c8dcSSimon Schubert }
31065796c8dcSSimon Schubert s = kept;
31075796c8dcSSimon Schubert }
31085796c8dcSSimon Schubert
31095796c8dcSSimon Schubert s = s->output_section;
31105796c8dcSSimon Schubert BFD_ASSERT (s != NULL);
31115796c8dcSSimon Schubert }
31125796c8dcSSimon Schubert else
31135796c8dcSSimon Schubert {
31145796c8dcSSimon Schubert /* Handle objcopy. */
31155796c8dcSSimon Schubert if (s->output_section == NULL)
31165796c8dcSSimon Schubert {
31175796c8dcSSimon Schubert (*_bfd_error_handler)
31185796c8dcSSimon Schubert (_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"),
31195796c8dcSSimon Schubert abfd, d->this_hdr.bfd_section, s, s->owner);
31205796c8dcSSimon Schubert bfd_set_error (bfd_error_bad_value);
31215796c8dcSSimon Schubert return FALSE;
31225796c8dcSSimon Schubert }
31235796c8dcSSimon Schubert s = s->output_section;
31245796c8dcSSimon Schubert }
31255796c8dcSSimon Schubert d->this_hdr.sh_link = elf_section_data (s)->this_idx;
31265796c8dcSSimon Schubert }
31275796c8dcSSimon Schubert else
31285796c8dcSSimon Schubert {
31295796c8dcSSimon Schubert /* PR 290:
31305796c8dcSSimon Schubert The Intel C compiler generates SHT_IA_64_UNWIND with
31315796c8dcSSimon Schubert SHF_LINK_ORDER. But it doesn't set the sh_link or
31325796c8dcSSimon Schubert sh_info fields. Hence we could get the situation
31335796c8dcSSimon Schubert where s is NULL. */
31345796c8dcSSimon Schubert const struct elf_backend_data *bed
31355796c8dcSSimon Schubert = get_elf_backend_data (abfd);
31365796c8dcSSimon Schubert if (bed->link_order_error_handler)
31375796c8dcSSimon Schubert bed->link_order_error_handler
31385796c8dcSSimon Schubert (_("%B: warning: sh_link not set for section `%A'"),
31395796c8dcSSimon Schubert abfd, sec);
31405796c8dcSSimon Schubert }
31415796c8dcSSimon Schubert }
31425796c8dcSSimon Schubert
31435796c8dcSSimon Schubert switch (d->this_hdr.sh_type)
31445796c8dcSSimon Schubert {
31455796c8dcSSimon Schubert case SHT_REL:
31465796c8dcSSimon Schubert case SHT_RELA:
31475796c8dcSSimon Schubert /* A reloc section which we are treating as a normal BFD
31485796c8dcSSimon Schubert section. sh_link is the section index of the symbol
31495796c8dcSSimon Schubert table. sh_info is the section index of the section to
31505796c8dcSSimon Schubert which the relocation entries apply. We assume that an
31515796c8dcSSimon Schubert allocated reloc section uses the dynamic symbol table.
31525796c8dcSSimon Schubert FIXME: How can we be sure? */
31535796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, ".dynsym");
31545796c8dcSSimon Schubert if (s != NULL)
31555796c8dcSSimon Schubert d->this_hdr.sh_link = elf_section_data (s)->this_idx;
31565796c8dcSSimon Schubert
31575796c8dcSSimon Schubert /* We look up the section the relocs apply to by name. */
31585796c8dcSSimon Schubert name = sec->name;
31595796c8dcSSimon Schubert if (d->this_hdr.sh_type == SHT_REL)
31605796c8dcSSimon Schubert name += 4;
31615796c8dcSSimon Schubert else
31625796c8dcSSimon Schubert name += 5;
31635796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, name);
31645796c8dcSSimon Schubert if (s != NULL)
31655796c8dcSSimon Schubert d->this_hdr.sh_info = elf_section_data (s)->this_idx;
31665796c8dcSSimon Schubert break;
31675796c8dcSSimon Schubert
31685796c8dcSSimon Schubert case SHT_STRTAB:
31695796c8dcSSimon Schubert /* We assume that a section named .stab*str is a stabs
31705796c8dcSSimon Schubert string section. We look for a section with the same name
31715796c8dcSSimon Schubert but without the trailing ``str'', and set its sh_link
31725796c8dcSSimon Schubert field to point to this section. */
31735796c8dcSSimon Schubert if (CONST_STRNEQ (sec->name, ".stab")
31745796c8dcSSimon Schubert && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
31755796c8dcSSimon Schubert {
31765796c8dcSSimon Schubert size_t len;
31775796c8dcSSimon Schubert char *alc;
31785796c8dcSSimon Schubert
31795796c8dcSSimon Schubert len = strlen (sec->name);
31805796c8dcSSimon Schubert alc = (char *) bfd_malloc (len - 2);
31815796c8dcSSimon Schubert if (alc == NULL)
31825796c8dcSSimon Schubert return FALSE;
31835796c8dcSSimon Schubert memcpy (alc, sec->name, len - 3);
31845796c8dcSSimon Schubert alc[len - 3] = '\0';
31855796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, alc);
31865796c8dcSSimon Schubert free (alc);
31875796c8dcSSimon Schubert if (s != NULL)
31885796c8dcSSimon Schubert {
31895796c8dcSSimon Schubert elf_section_data (s)->this_hdr.sh_link = d->this_idx;
31905796c8dcSSimon Schubert
31915796c8dcSSimon Schubert /* This is a .stab section. */
31925796c8dcSSimon Schubert if (elf_section_data (s)->this_hdr.sh_entsize == 0)
31935796c8dcSSimon Schubert elf_section_data (s)->this_hdr.sh_entsize
31945796c8dcSSimon Schubert = 4 + 2 * bfd_get_arch_size (abfd) / 8;
31955796c8dcSSimon Schubert }
31965796c8dcSSimon Schubert }
31975796c8dcSSimon Schubert break;
31985796c8dcSSimon Schubert
31995796c8dcSSimon Schubert case SHT_DYNAMIC:
32005796c8dcSSimon Schubert case SHT_DYNSYM:
32015796c8dcSSimon Schubert case SHT_GNU_verneed:
32025796c8dcSSimon Schubert case SHT_GNU_verdef:
32035796c8dcSSimon Schubert /* sh_link is the section header index of the string table
32045796c8dcSSimon Schubert used for the dynamic entries, or the symbol table, or the
32055796c8dcSSimon Schubert version strings. */
32065796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, ".dynstr");
32075796c8dcSSimon Schubert if (s != NULL)
32085796c8dcSSimon Schubert d->this_hdr.sh_link = elf_section_data (s)->this_idx;
32095796c8dcSSimon Schubert break;
32105796c8dcSSimon Schubert
32115796c8dcSSimon Schubert case SHT_GNU_LIBLIST:
32125796c8dcSSimon Schubert /* sh_link is the section header index of the prelink library
32135796c8dcSSimon Schubert list used for the dynamic entries, or the symbol table, or
32145796c8dcSSimon Schubert the version strings. */
32155796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC)
32165796c8dcSSimon Schubert ? ".dynstr" : ".gnu.libstr");
32175796c8dcSSimon Schubert if (s != NULL)
32185796c8dcSSimon Schubert d->this_hdr.sh_link = elf_section_data (s)->this_idx;
32195796c8dcSSimon Schubert break;
32205796c8dcSSimon Schubert
32215796c8dcSSimon Schubert case SHT_HASH:
32225796c8dcSSimon Schubert case SHT_GNU_HASH:
32235796c8dcSSimon Schubert case SHT_GNU_versym:
32245796c8dcSSimon Schubert /* sh_link is the section header index of the symbol table
32255796c8dcSSimon Schubert this hash table or version table is for. */
32265796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, ".dynsym");
32275796c8dcSSimon Schubert if (s != NULL)
32285796c8dcSSimon Schubert d->this_hdr.sh_link = elf_section_data (s)->this_idx;
32295796c8dcSSimon Schubert break;
32305796c8dcSSimon Schubert
32315796c8dcSSimon Schubert case SHT_GROUP:
3232*ef5ccd6cSJohn Marino d->this_hdr.sh_link = elf_onesymtab (abfd);
32335796c8dcSSimon Schubert }
32345796c8dcSSimon Schubert }
32355796c8dcSSimon Schubert
32365796c8dcSSimon Schubert for (secn = 1; secn < section_number; ++secn)
32375796c8dcSSimon Schubert if (i_shdrp[secn] == NULL)
32385796c8dcSSimon Schubert i_shdrp[secn] = i_shdrp[0];
32395796c8dcSSimon Schubert else
32405796c8dcSSimon Schubert i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
32415796c8dcSSimon Schubert i_shdrp[secn]->sh_name);
32425796c8dcSSimon Schubert return TRUE;
32435796c8dcSSimon Schubert }
32445796c8dcSSimon Schubert
32455796c8dcSSimon Schubert static bfd_boolean
sym_is_global(bfd * abfd,asymbol * sym)32465796c8dcSSimon Schubert sym_is_global (bfd *abfd, asymbol *sym)
32475796c8dcSSimon Schubert {
32485796c8dcSSimon Schubert /* If the backend has a special mapping, use it. */
32495796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
32505796c8dcSSimon Schubert if (bed->elf_backend_sym_is_global)
32515796c8dcSSimon Schubert return (*bed->elf_backend_sym_is_global) (abfd, sym);
32525796c8dcSSimon Schubert
32535796c8dcSSimon Schubert return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
32545796c8dcSSimon Schubert || bfd_is_und_section (bfd_get_section (sym))
32555796c8dcSSimon Schubert || bfd_is_com_section (bfd_get_section (sym)));
32565796c8dcSSimon Schubert }
32575796c8dcSSimon Schubert
32585796c8dcSSimon Schubert /* Don't output section symbols for sections that are not going to be
3259*ef5ccd6cSJohn Marino output, that are duplicates or there is no BFD section. */
32605796c8dcSSimon Schubert
32615796c8dcSSimon Schubert static bfd_boolean
ignore_section_sym(bfd * abfd,asymbol * sym)32625796c8dcSSimon Schubert ignore_section_sym (bfd *abfd, asymbol *sym)
32635796c8dcSSimon Schubert {
3264*ef5ccd6cSJohn Marino elf_symbol_type *type_ptr;
3265*ef5ccd6cSJohn Marino
3266*ef5ccd6cSJohn Marino if ((sym->flags & BSF_SECTION_SYM) == 0)
3267*ef5ccd6cSJohn Marino return FALSE;
3268*ef5ccd6cSJohn Marino
3269*ef5ccd6cSJohn Marino type_ptr = elf_symbol_from (abfd, sym);
3270*ef5ccd6cSJohn Marino return ((type_ptr != NULL
3271*ef5ccd6cSJohn Marino && type_ptr->internal_elf_sym.st_shndx != 0
3272*ef5ccd6cSJohn Marino && bfd_is_abs_section (sym->section))
3273*ef5ccd6cSJohn Marino || !(sym->section->owner == abfd
32745796c8dcSSimon Schubert || (sym->section->output_section->owner == abfd
3275*ef5ccd6cSJohn Marino && sym->section->output_offset == 0)
3276*ef5ccd6cSJohn Marino || bfd_is_abs_section (sym->section)));
32775796c8dcSSimon Schubert }
32785796c8dcSSimon Schubert
3279*ef5ccd6cSJohn Marino /* Map symbol from it's internal number to the external number, moving
3280*ef5ccd6cSJohn Marino all local symbols to be at the head of the list. */
3281*ef5ccd6cSJohn Marino
32825796c8dcSSimon Schubert static bfd_boolean
elf_map_symbols(bfd * abfd,unsigned int * pnum_locals)3283*ef5ccd6cSJohn Marino elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
32845796c8dcSSimon Schubert {
32855796c8dcSSimon Schubert unsigned int symcount = bfd_get_symcount (abfd);
32865796c8dcSSimon Schubert asymbol **syms = bfd_get_outsymbols (abfd);
32875796c8dcSSimon Schubert asymbol **sect_syms;
32885796c8dcSSimon Schubert unsigned int num_locals = 0;
32895796c8dcSSimon Schubert unsigned int num_globals = 0;
32905796c8dcSSimon Schubert unsigned int num_locals2 = 0;
32915796c8dcSSimon Schubert unsigned int num_globals2 = 0;
32925796c8dcSSimon Schubert int max_index = 0;
32935796c8dcSSimon Schubert unsigned int idx;
32945796c8dcSSimon Schubert asection *asect;
32955796c8dcSSimon Schubert asymbol **new_syms;
32965796c8dcSSimon Schubert
32975796c8dcSSimon Schubert #ifdef DEBUG
32985796c8dcSSimon Schubert fprintf (stderr, "elf_map_symbols\n");
32995796c8dcSSimon Schubert fflush (stderr);
33005796c8dcSSimon Schubert #endif
33015796c8dcSSimon Schubert
33025796c8dcSSimon Schubert for (asect = abfd->sections; asect; asect = asect->next)
33035796c8dcSSimon Schubert {
33045796c8dcSSimon Schubert if (max_index < asect->index)
33055796c8dcSSimon Schubert max_index = asect->index;
33065796c8dcSSimon Schubert }
33075796c8dcSSimon Schubert
33085796c8dcSSimon Schubert max_index++;
33095796c8dcSSimon Schubert sect_syms = (asymbol **) bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
33105796c8dcSSimon Schubert if (sect_syms == NULL)
33115796c8dcSSimon Schubert return FALSE;
33125796c8dcSSimon Schubert elf_section_syms (abfd) = sect_syms;
33135796c8dcSSimon Schubert elf_num_section_syms (abfd) = max_index;
33145796c8dcSSimon Schubert
33155796c8dcSSimon Schubert /* Init sect_syms entries for any section symbols we have already
33165796c8dcSSimon Schubert decided to output. */
33175796c8dcSSimon Schubert for (idx = 0; idx < symcount; idx++)
33185796c8dcSSimon Schubert {
33195796c8dcSSimon Schubert asymbol *sym = syms[idx];
33205796c8dcSSimon Schubert
33215796c8dcSSimon Schubert if ((sym->flags & BSF_SECTION_SYM) != 0
33225796c8dcSSimon Schubert && sym->value == 0
3323*ef5ccd6cSJohn Marino && !ignore_section_sym (abfd, sym)
3324*ef5ccd6cSJohn Marino && !bfd_is_abs_section (sym->section))
33255796c8dcSSimon Schubert {
33265796c8dcSSimon Schubert asection *sec = sym->section;
33275796c8dcSSimon Schubert
33285796c8dcSSimon Schubert if (sec->owner != abfd)
33295796c8dcSSimon Schubert sec = sec->output_section;
33305796c8dcSSimon Schubert
33315796c8dcSSimon Schubert sect_syms[sec->index] = syms[idx];
33325796c8dcSSimon Schubert }
33335796c8dcSSimon Schubert }
33345796c8dcSSimon Schubert
33355796c8dcSSimon Schubert /* Classify all of the symbols. */
33365796c8dcSSimon Schubert for (idx = 0; idx < symcount; idx++)
33375796c8dcSSimon Schubert {
3338*ef5ccd6cSJohn Marino if (sym_is_global (abfd, syms[idx]))
33395796c8dcSSimon Schubert num_globals++;
3340*ef5ccd6cSJohn Marino else if (!ignore_section_sym (abfd, syms[idx]))
3341*ef5ccd6cSJohn Marino num_locals++;
33425796c8dcSSimon Schubert }
33435796c8dcSSimon Schubert
33445796c8dcSSimon Schubert /* We will be adding a section symbol for each normal BFD section. Most
33455796c8dcSSimon Schubert sections will already have a section symbol in outsymbols, but
33465796c8dcSSimon Schubert eg. SHT_GROUP sections will not, and we need the section symbol mapped
33475796c8dcSSimon Schubert at least in that case. */
33485796c8dcSSimon Schubert for (asect = abfd->sections; asect; asect = asect->next)
33495796c8dcSSimon Schubert {
33505796c8dcSSimon Schubert if (sect_syms[asect->index] == NULL)
33515796c8dcSSimon Schubert {
33525796c8dcSSimon Schubert if (!sym_is_global (abfd, asect->symbol))
33535796c8dcSSimon Schubert num_locals++;
33545796c8dcSSimon Schubert else
33555796c8dcSSimon Schubert num_globals++;
33565796c8dcSSimon Schubert }
33575796c8dcSSimon Schubert }
33585796c8dcSSimon Schubert
33595796c8dcSSimon Schubert /* Now sort the symbols so the local symbols are first. */
33605796c8dcSSimon Schubert new_syms = (asymbol **) bfd_alloc2 (abfd, num_locals + num_globals,
33615796c8dcSSimon Schubert sizeof (asymbol *));
33625796c8dcSSimon Schubert
33635796c8dcSSimon Schubert if (new_syms == NULL)
33645796c8dcSSimon Schubert return FALSE;
33655796c8dcSSimon Schubert
33665796c8dcSSimon Schubert for (idx = 0; idx < symcount; idx++)
33675796c8dcSSimon Schubert {
33685796c8dcSSimon Schubert asymbol *sym = syms[idx];
33695796c8dcSSimon Schubert unsigned int i;
33705796c8dcSSimon Schubert
3371*ef5ccd6cSJohn Marino if (sym_is_global (abfd, sym))
3372*ef5ccd6cSJohn Marino i = num_locals + num_globals2++;
3373*ef5ccd6cSJohn Marino else if (!ignore_section_sym (abfd, sym))
33745796c8dcSSimon Schubert i = num_locals2++;
33755796c8dcSSimon Schubert else
3376*ef5ccd6cSJohn Marino continue;
33775796c8dcSSimon Schubert new_syms[i] = sym;
33785796c8dcSSimon Schubert sym->udata.i = i + 1;
33795796c8dcSSimon Schubert }
33805796c8dcSSimon Schubert for (asect = abfd->sections; asect; asect = asect->next)
33815796c8dcSSimon Schubert {
33825796c8dcSSimon Schubert if (sect_syms[asect->index] == NULL)
33835796c8dcSSimon Schubert {
33845796c8dcSSimon Schubert asymbol *sym = asect->symbol;
33855796c8dcSSimon Schubert unsigned int i;
33865796c8dcSSimon Schubert
33875796c8dcSSimon Schubert sect_syms[asect->index] = sym;
33885796c8dcSSimon Schubert if (!sym_is_global (abfd, sym))
33895796c8dcSSimon Schubert i = num_locals2++;
33905796c8dcSSimon Schubert else
33915796c8dcSSimon Schubert i = num_locals + num_globals2++;
33925796c8dcSSimon Schubert new_syms[i] = sym;
33935796c8dcSSimon Schubert sym->udata.i = i + 1;
33945796c8dcSSimon Schubert }
33955796c8dcSSimon Schubert }
33965796c8dcSSimon Schubert
33975796c8dcSSimon Schubert bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
33985796c8dcSSimon Schubert
3399*ef5ccd6cSJohn Marino *pnum_locals = num_locals;
34005796c8dcSSimon Schubert return TRUE;
34015796c8dcSSimon Schubert }
34025796c8dcSSimon Schubert
34035796c8dcSSimon Schubert /* Align to the maximum file alignment that could be required for any
34045796c8dcSSimon Schubert ELF data structure. */
34055796c8dcSSimon Schubert
34065796c8dcSSimon Schubert static inline file_ptr
align_file_position(file_ptr off,int align)34075796c8dcSSimon Schubert align_file_position (file_ptr off, int align)
34085796c8dcSSimon Schubert {
34095796c8dcSSimon Schubert return (off + align - 1) & ~(align - 1);
34105796c8dcSSimon Schubert }
34115796c8dcSSimon Schubert
34125796c8dcSSimon Schubert /* Assign a file position to a section, optionally aligning to the
34135796c8dcSSimon Schubert required section alignment. */
34145796c8dcSSimon Schubert
34155796c8dcSSimon Schubert file_ptr
_bfd_elf_assign_file_position_for_section(Elf_Internal_Shdr * i_shdrp,file_ptr offset,bfd_boolean align)34165796c8dcSSimon Schubert _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
34175796c8dcSSimon Schubert file_ptr offset,
34185796c8dcSSimon Schubert bfd_boolean align)
34195796c8dcSSimon Schubert {
34205796c8dcSSimon Schubert if (align && i_shdrp->sh_addralign > 1)
34215796c8dcSSimon Schubert offset = BFD_ALIGN (offset, i_shdrp->sh_addralign);
34225796c8dcSSimon Schubert i_shdrp->sh_offset = offset;
34235796c8dcSSimon Schubert if (i_shdrp->bfd_section != NULL)
34245796c8dcSSimon Schubert i_shdrp->bfd_section->filepos = offset;
34255796c8dcSSimon Schubert if (i_shdrp->sh_type != SHT_NOBITS)
34265796c8dcSSimon Schubert offset += i_shdrp->sh_size;
34275796c8dcSSimon Schubert return offset;
34285796c8dcSSimon Schubert }
34295796c8dcSSimon Schubert
34305796c8dcSSimon Schubert /* Compute the file positions we are going to put the sections at, and
34315796c8dcSSimon Schubert otherwise prepare to begin writing out the ELF file. If LINK_INFO
34325796c8dcSSimon Schubert is not NULL, this is being called by the ELF backend linker. */
34335796c8dcSSimon Schubert
34345796c8dcSSimon Schubert bfd_boolean
_bfd_elf_compute_section_file_positions(bfd * abfd,struct bfd_link_info * link_info)34355796c8dcSSimon Schubert _bfd_elf_compute_section_file_positions (bfd *abfd,
34365796c8dcSSimon Schubert struct bfd_link_info *link_info)
34375796c8dcSSimon Schubert {
34385796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3439c50c785cSJohn Marino struct fake_section_arg fsargs;
34405796c8dcSSimon Schubert bfd_boolean failed;
34415796c8dcSSimon Schubert struct bfd_strtab_hash *strtab = NULL;
34425796c8dcSSimon Schubert Elf_Internal_Shdr *shstrtab_hdr;
34435796c8dcSSimon Schubert bfd_boolean need_symtab;
34445796c8dcSSimon Schubert
34455796c8dcSSimon Schubert if (abfd->output_has_begun)
34465796c8dcSSimon Schubert return TRUE;
34475796c8dcSSimon Schubert
34485796c8dcSSimon Schubert /* Do any elf backend specific processing first. */
34495796c8dcSSimon Schubert if (bed->elf_backend_begin_write_processing)
34505796c8dcSSimon Schubert (*bed->elf_backend_begin_write_processing) (abfd, link_info);
34515796c8dcSSimon Schubert
34525796c8dcSSimon Schubert if (! prep_headers (abfd))
34535796c8dcSSimon Schubert return FALSE;
34545796c8dcSSimon Schubert
34555796c8dcSSimon Schubert /* Post process the headers if necessary. */
34565796c8dcSSimon Schubert if (bed->elf_backend_post_process_headers)
34575796c8dcSSimon Schubert (*bed->elf_backend_post_process_headers) (abfd, link_info);
34585796c8dcSSimon Schubert
3459c50c785cSJohn Marino fsargs.failed = FALSE;
3460c50c785cSJohn Marino fsargs.link_info = link_info;
3461c50c785cSJohn Marino bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
3462c50c785cSJohn Marino if (fsargs.failed)
34635796c8dcSSimon Schubert return FALSE;
34645796c8dcSSimon Schubert
34655796c8dcSSimon Schubert if (!assign_section_numbers (abfd, link_info))
34665796c8dcSSimon Schubert return FALSE;
34675796c8dcSSimon Schubert
34685796c8dcSSimon Schubert /* The backend linker builds symbol table information itself. */
34695796c8dcSSimon Schubert need_symtab = (link_info == NULL
34705796c8dcSSimon Schubert && (bfd_get_symcount (abfd) > 0
34715796c8dcSSimon Schubert || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
34725796c8dcSSimon Schubert == HAS_RELOC)));
34735796c8dcSSimon Schubert if (need_symtab)
34745796c8dcSSimon Schubert {
34755796c8dcSSimon Schubert /* Non-zero if doing a relocatable link. */
34765796c8dcSSimon Schubert int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
34775796c8dcSSimon Schubert
34785796c8dcSSimon Schubert if (! swap_out_syms (abfd, &strtab, relocatable_p))
34795796c8dcSSimon Schubert return FALSE;
34805796c8dcSSimon Schubert }
34815796c8dcSSimon Schubert
3482c50c785cSJohn Marino failed = FALSE;
34835796c8dcSSimon Schubert if (link_info == NULL)
34845796c8dcSSimon Schubert {
34855796c8dcSSimon Schubert bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
34865796c8dcSSimon Schubert if (failed)
34875796c8dcSSimon Schubert return FALSE;
34885796c8dcSSimon Schubert }
34895796c8dcSSimon Schubert
34905796c8dcSSimon Schubert shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
34915796c8dcSSimon Schubert /* sh_name was set in prep_headers. */
34925796c8dcSSimon Schubert shstrtab_hdr->sh_type = SHT_STRTAB;
34935796c8dcSSimon Schubert shstrtab_hdr->sh_flags = 0;
34945796c8dcSSimon Schubert shstrtab_hdr->sh_addr = 0;
34955796c8dcSSimon Schubert shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
34965796c8dcSSimon Schubert shstrtab_hdr->sh_entsize = 0;
34975796c8dcSSimon Schubert shstrtab_hdr->sh_link = 0;
34985796c8dcSSimon Schubert shstrtab_hdr->sh_info = 0;
34995796c8dcSSimon Schubert /* sh_offset is set in assign_file_positions_except_relocs. */
35005796c8dcSSimon Schubert shstrtab_hdr->sh_addralign = 1;
35015796c8dcSSimon Schubert
35025796c8dcSSimon Schubert if (!assign_file_positions_except_relocs (abfd, link_info))
35035796c8dcSSimon Schubert return FALSE;
35045796c8dcSSimon Schubert
35055796c8dcSSimon Schubert if (need_symtab)
35065796c8dcSSimon Schubert {
35075796c8dcSSimon Schubert file_ptr off;
35085796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
35095796c8dcSSimon Schubert
3510*ef5ccd6cSJohn Marino off = elf_next_file_pos (abfd);
35115796c8dcSSimon Schubert
35125796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->symtab_hdr;
35135796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
35145796c8dcSSimon Schubert
35155796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
35165796c8dcSSimon Schubert if (hdr->sh_size != 0)
35175796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
35185796c8dcSSimon Schubert
35195796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->strtab_hdr;
35205796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
35215796c8dcSSimon Schubert
3522*ef5ccd6cSJohn Marino elf_next_file_pos (abfd) = off;
35235796c8dcSSimon Schubert
35245796c8dcSSimon Schubert /* Now that we know where the .strtab section goes, write it
35255796c8dcSSimon Schubert out. */
35265796c8dcSSimon Schubert if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
35275796c8dcSSimon Schubert || ! _bfd_stringtab_emit (abfd, strtab))
35285796c8dcSSimon Schubert return FALSE;
35295796c8dcSSimon Schubert _bfd_stringtab_free (strtab);
35305796c8dcSSimon Schubert }
35315796c8dcSSimon Schubert
35325796c8dcSSimon Schubert abfd->output_has_begun = TRUE;
35335796c8dcSSimon Schubert
35345796c8dcSSimon Schubert return TRUE;
35355796c8dcSSimon Schubert }
35365796c8dcSSimon Schubert
35375796c8dcSSimon Schubert /* Make an initial estimate of the size of the program header. If we
35385796c8dcSSimon Schubert get the number wrong here, we'll redo section placement. */
35395796c8dcSSimon Schubert
35405796c8dcSSimon Schubert static bfd_size_type
get_program_header_size(bfd * abfd,struct bfd_link_info * info)35415796c8dcSSimon Schubert get_program_header_size (bfd *abfd, struct bfd_link_info *info)
35425796c8dcSSimon Schubert {
35435796c8dcSSimon Schubert size_t segs;
35445796c8dcSSimon Schubert asection *s;
35455796c8dcSSimon Schubert const struct elf_backend_data *bed;
35465796c8dcSSimon Schubert
35475796c8dcSSimon Schubert /* Assume we will need exactly two PT_LOAD segments: one for text
35485796c8dcSSimon Schubert and one for data. */
35495796c8dcSSimon Schubert segs = 2;
35505796c8dcSSimon Schubert
35515796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, ".interp");
35525796c8dcSSimon Schubert if (s != NULL && (s->flags & SEC_LOAD) != 0)
35535796c8dcSSimon Schubert {
35545796c8dcSSimon Schubert /* If we have a loadable interpreter section, we need a
35555796c8dcSSimon Schubert PT_INTERP segment. In this case, assume we also need a
35565796c8dcSSimon Schubert PT_PHDR segment, although that may not be true for all
35575796c8dcSSimon Schubert targets. */
35585796c8dcSSimon Schubert segs += 2;
35595796c8dcSSimon Schubert }
35605796c8dcSSimon Schubert
35615796c8dcSSimon Schubert if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
35625796c8dcSSimon Schubert {
35635796c8dcSSimon Schubert /* We need a PT_DYNAMIC segment. */
35645796c8dcSSimon Schubert ++segs;
35655796c8dcSSimon Schubert }
35665796c8dcSSimon Schubert
35675796c8dcSSimon Schubert if (info != NULL && info->relro)
35685796c8dcSSimon Schubert {
35695796c8dcSSimon Schubert /* We need a PT_GNU_RELRO segment. */
35705796c8dcSSimon Schubert ++segs;
35715796c8dcSSimon Schubert }
35725796c8dcSSimon Schubert
3573*ef5ccd6cSJohn Marino if (elf_eh_frame_hdr (abfd))
35745796c8dcSSimon Schubert {
35755796c8dcSSimon Schubert /* We need a PT_GNU_EH_FRAME segment. */
35765796c8dcSSimon Schubert ++segs;
35775796c8dcSSimon Schubert }
35785796c8dcSSimon Schubert
3579*ef5ccd6cSJohn Marino if (elf_stack_flags (abfd))
35805796c8dcSSimon Schubert {
35815796c8dcSSimon Schubert /* We need a PT_GNU_STACK segment. */
35825796c8dcSSimon Schubert ++segs;
35835796c8dcSSimon Schubert }
35845796c8dcSSimon Schubert
35855796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
35865796c8dcSSimon Schubert {
35875796c8dcSSimon Schubert if ((s->flags & SEC_LOAD) != 0
35885796c8dcSSimon Schubert && CONST_STRNEQ (s->name, ".note"))
35895796c8dcSSimon Schubert {
35905796c8dcSSimon Schubert /* We need a PT_NOTE segment. */
35915796c8dcSSimon Schubert ++segs;
35925796c8dcSSimon Schubert /* Try to create just one PT_NOTE segment
35935796c8dcSSimon Schubert for all adjacent loadable .note* sections.
35945796c8dcSSimon Schubert gABI requires that within a PT_NOTE segment
35955796c8dcSSimon Schubert (and also inside of each SHT_NOTE section)
35965796c8dcSSimon Schubert each note is padded to a multiple of 4 size,
35975796c8dcSSimon Schubert so we check whether the sections are correctly
35985796c8dcSSimon Schubert aligned. */
35995796c8dcSSimon Schubert if (s->alignment_power == 2)
36005796c8dcSSimon Schubert while (s->next != NULL
36015796c8dcSSimon Schubert && s->next->alignment_power == 2
36025796c8dcSSimon Schubert && (s->next->flags & SEC_LOAD) != 0
36035796c8dcSSimon Schubert && CONST_STRNEQ (s->next->name, ".note"))
36045796c8dcSSimon Schubert s = s->next;
36055796c8dcSSimon Schubert }
36065796c8dcSSimon Schubert }
36075796c8dcSSimon Schubert
36085796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
36095796c8dcSSimon Schubert {
36105796c8dcSSimon Schubert if (s->flags & SEC_THREAD_LOCAL)
36115796c8dcSSimon Schubert {
36125796c8dcSSimon Schubert /* We need a PT_TLS segment. */
36135796c8dcSSimon Schubert ++segs;
36145796c8dcSSimon Schubert break;
36155796c8dcSSimon Schubert }
36165796c8dcSSimon Schubert }
36175796c8dcSSimon Schubert
36185796c8dcSSimon Schubert /* Let the backend count up any program headers it might need. */
36195796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
36205796c8dcSSimon Schubert if (bed->elf_backend_additional_program_headers)
36215796c8dcSSimon Schubert {
36225796c8dcSSimon Schubert int a;
36235796c8dcSSimon Schubert
36245796c8dcSSimon Schubert a = (*bed->elf_backend_additional_program_headers) (abfd, info);
36255796c8dcSSimon Schubert if (a == -1)
36265796c8dcSSimon Schubert abort ();
36275796c8dcSSimon Schubert segs += a;
36285796c8dcSSimon Schubert }
36295796c8dcSSimon Schubert
36305796c8dcSSimon Schubert return segs * bed->s->sizeof_phdr;
36315796c8dcSSimon Schubert }
36325796c8dcSSimon Schubert
36335796c8dcSSimon Schubert /* Find the segment that contains the output_section of section. */
36345796c8dcSSimon Schubert
36355796c8dcSSimon Schubert Elf_Internal_Phdr *
_bfd_elf_find_segment_containing_section(bfd * abfd,asection * section)36365796c8dcSSimon Schubert _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
36375796c8dcSSimon Schubert {
36385796c8dcSSimon Schubert struct elf_segment_map *m;
36395796c8dcSSimon Schubert Elf_Internal_Phdr *p;
36405796c8dcSSimon Schubert
3641*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr;
36425796c8dcSSimon Schubert m != NULL;
36435796c8dcSSimon Schubert m = m->next, p++)
36445796c8dcSSimon Schubert {
36455796c8dcSSimon Schubert int i;
36465796c8dcSSimon Schubert
36475796c8dcSSimon Schubert for (i = m->count - 1; i >= 0; i--)
36485796c8dcSSimon Schubert if (m->sections[i] == section)
36495796c8dcSSimon Schubert return p;
36505796c8dcSSimon Schubert }
36515796c8dcSSimon Schubert
36525796c8dcSSimon Schubert return NULL;
36535796c8dcSSimon Schubert }
36545796c8dcSSimon Schubert
36555796c8dcSSimon Schubert /* Create a mapping from a set of sections to a program segment. */
36565796c8dcSSimon Schubert
36575796c8dcSSimon Schubert static struct elf_segment_map *
make_mapping(bfd * abfd,asection ** sections,unsigned int from,unsigned int to,bfd_boolean phdr)36585796c8dcSSimon Schubert make_mapping (bfd *abfd,
36595796c8dcSSimon Schubert asection **sections,
36605796c8dcSSimon Schubert unsigned int from,
36615796c8dcSSimon Schubert unsigned int to,
36625796c8dcSSimon Schubert bfd_boolean phdr)
36635796c8dcSSimon Schubert {
36645796c8dcSSimon Schubert struct elf_segment_map *m;
36655796c8dcSSimon Schubert unsigned int i;
36665796c8dcSSimon Schubert asection **hdrpp;
36675796c8dcSSimon Schubert bfd_size_type amt;
36685796c8dcSSimon Schubert
36695796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
36705796c8dcSSimon Schubert amt += (to - from - 1) * sizeof (asection *);
36715796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
36725796c8dcSSimon Schubert if (m == NULL)
36735796c8dcSSimon Schubert return NULL;
36745796c8dcSSimon Schubert m->next = NULL;
36755796c8dcSSimon Schubert m->p_type = PT_LOAD;
36765796c8dcSSimon Schubert for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
36775796c8dcSSimon Schubert m->sections[i - from] = *hdrpp;
36785796c8dcSSimon Schubert m->count = to - from;
36795796c8dcSSimon Schubert
36805796c8dcSSimon Schubert if (from == 0 && phdr)
36815796c8dcSSimon Schubert {
36825796c8dcSSimon Schubert /* Include the headers in the first PT_LOAD segment. */
36835796c8dcSSimon Schubert m->includes_filehdr = 1;
36845796c8dcSSimon Schubert m->includes_phdrs = 1;
36855796c8dcSSimon Schubert }
36865796c8dcSSimon Schubert
36875796c8dcSSimon Schubert return m;
36885796c8dcSSimon Schubert }
36895796c8dcSSimon Schubert
36905796c8dcSSimon Schubert /* Create the PT_DYNAMIC segment, which includes DYNSEC. Returns NULL
36915796c8dcSSimon Schubert on failure. */
36925796c8dcSSimon Schubert
36935796c8dcSSimon Schubert struct elf_segment_map *
_bfd_elf_make_dynamic_segment(bfd * abfd,asection * dynsec)36945796c8dcSSimon Schubert _bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
36955796c8dcSSimon Schubert {
36965796c8dcSSimon Schubert struct elf_segment_map *m;
36975796c8dcSSimon Schubert
36985796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd,
36995796c8dcSSimon Schubert sizeof (struct elf_segment_map));
37005796c8dcSSimon Schubert if (m == NULL)
37015796c8dcSSimon Schubert return NULL;
37025796c8dcSSimon Schubert m->next = NULL;
37035796c8dcSSimon Schubert m->p_type = PT_DYNAMIC;
37045796c8dcSSimon Schubert m->count = 1;
37055796c8dcSSimon Schubert m->sections[0] = dynsec;
37065796c8dcSSimon Schubert
37075796c8dcSSimon Schubert return m;
37085796c8dcSSimon Schubert }
37095796c8dcSSimon Schubert
37105796c8dcSSimon Schubert /* Possibly add or remove segments from the segment map. */
37115796c8dcSSimon Schubert
37125796c8dcSSimon Schubert static bfd_boolean
elf_modify_segment_map(bfd * abfd,struct bfd_link_info * info,bfd_boolean remove_empty_load)37135796c8dcSSimon Schubert elf_modify_segment_map (bfd *abfd,
37145796c8dcSSimon Schubert struct bfd_link_info *info,
37155796c8dcSSimon Schubert bfd_boolean remove_empty_load)
37165796c8dcSSimon Schubert {
37175796c8dcSSimon Schubert struct elf_segment_map **m;
37185796c8dcSSimon Schubert const struct elf_backend_data *bed;
37195796c8dcSSimon Schubert
37205796c8dcSSimon Schubert /* The placement algorithm assumes that non allocated sections are
37215796c8dcSSimon Schubert not in PT_LOAD segments. We ensure this here by removing such
37225796c8dcSSimon Schubert sections from the segment map. We also remove excluded
37235796c8dcSSimon Schubert sections. Finally, any PT_LOAD segment without sections is
37245796c8dcSSimon Schubert removed. */
3725*ef5ccd6cSJohn Marino m = &elf_seg_map (abfd);
37265796c8dcSSimon Schubert while (*m)
37275796c8dcSSimon Schubert {
37285796c8dcSSimon Schubert unsigned int i, new_count;
37295796c8dcSSimon Schubert
37305796c8dcSSimon Schubert for (new_count = 0, i = 0; i < (*m)->count; i++)
37315796c8dcSSimon Schubert {
37325796c8dcSSimon Schubert if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
37335796c8dcSSimon Schubert && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
37345796c8dcSSimon Schubert || (*m)->p_type != PT_LOAD))
37355796c8dcSSimon Schubert {
37365796c8dcSSimon Schubert (*m)->sections[new_count] = (*m)->sections[i];
37375796c8dcSSimon Schubert new_count++;
37385796c8dcSSimon Schubert }
37395796c8dcSSimon Schubert }
37405796c8dcSSimon Schubert (*m)->count = new_count;
37415796c8dcSSimon Schubert
37425796c8dcSSimon Schubert if (remove_empty_load && (*m)->p_type == PT_LOAD && (*m)->count == 0)
37435796c8dcSSimon Schubert *m = (*m)->next;
37445796c8dcSSimon Schubert else
37455796c8dcSSimon Schubert m = &(*m)->next;
37465796c8dcSSimon Schubert }
37475796c8dcSSimon Schubert
37485796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
37495796c8dcSSimon Schubert if (bed->elf_backend_modify_segment_map != NULL)
37505796c8dcSSimon Schubert {
37515796c8dcSSimon Schubert if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
37525796c8dcSSimon Schubert return FALSE;
37535796c8dcSSimon Schubert }
37545796c8dcSSimon Schubert
37555796c8dcSSimon Schubert return TRUE;
37565796c8dcSSimon Schubert }
37575796c8dcSSimon Schubert
37585796c8dcSSimon Schubert /* Set up a mapping from BFD sections to program segments. */
37595796c8dcSSimon Schubert
37605796c8dcSSimon Schubert bfd_boolean
_bfd_elf_map_sections_to_segments(bfd * abfd,struct bfd_link_info * info)37615796c8dcSSimon Schubert _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
37625796c8dcSSimon Schubert {
37635796c8dcSSimon Schubert unsigned int count;
37645796c8dcSSimon Schubert struct elf_segment_map *m;
37655796c8dcSSimon Schubert asection **sections = NULL;
37665796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
37675796c8dcSSimon Schubert bfd_boolean no_user_phdrs;
37685796c8dcSSimon Schubert
3769*ef5ccd6cSJohn Marino no_user_phdrs = elf_seg_map (abfd) == NULL;
3770*ef5ccd6cSJohn Marino
3771*ef5ccd6cSJohn Marino if (info != NULL)
3772*ef5ccd6cSJohn Marino info->user_phdrs = !no_user_phdrs;
3773*ef5ccd6cSJohn Marino
37745796c8dcSSimon Schubert if (no_user_phdrs && bfd_count_sections (abfd) != 0)
37755796c8dcSSimon Schubert {
37765796c8dcSSimon Schubert asection *s;
37775796c8dcSSimon Schubert unsigned int i;
37785796c8dcSSimon Schubert struct elf_segment_map *mfirst;
37795796c8dcSSimon Schubert struct elf_segment_map **pm;
37805796c8dcSSimon Schubert asection *last_hdr;
37815796c8dcSSimon Schubert bfd_vma last_size;
37825796c8dcSSimon Schubert unsigned int phdr_index;
37835796c8dcSSimon Schubert bfd_vma maxpagesize;
37845796c8dcSSimon Schubert asection **hdrpp;
37855796c8dcSSimon Schubert bfd_boolean phdr_in_segment = TRUE;
37865796c8dcSSimon Schubert bfd_boolean writable;
37875796c8dcSSimon Schubert int tls_count = 0;
37885796c8dcSSimon Schubert asection *first_tls = NULL;
37895796c8dcSSimon Schubert asection *dynsec, *eh_frame_hdr;
37905796c8dcSSimon Schubert bfd_size_type amt;
3791c50c785cSJohn Marino bfd_vma addr_mask, wrap_to = 0;
37925796c8dcSSimon Schubert
37935796c8dcSSimon Schubert /* Select the allocated sections, and sort them. */
37945796c8dcSSimon Schubert
37955796c8dcSSimon Schubert sections = (asection **) bfd_malloc2 (bfd_count_sections (abfd),
37965796c8dcSSimon Schubert sizeof (asection *));
37975796c8dcSSimon Schubert if (sections == NULL)
37985796c8dcSSimon Schubert goto error_return;
37995796c8dcSSimon Schubert
3800c50c785cSJohn Marino /* Calculate top address, avoiding undefined behaviour of shift
3801c50c785cSJohn Marino left operator when shift count is equal to size of type
3802c50c785cSJohn Marino being shifted. */
3803c50c785cSJohn Marino addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1;
3804c50c785cSJohn Marino addr_mask = (addr_mask << 1) + 1;
3805c50c785cSJohn Marino
38065796c8dcSSimon Schubert i = 0;
38075796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
38085796c8dcSSimon Schubert {
38095796c8dcSSimon Schubert if ((s->flags & SEC_ALLOC) != 0)
38105796c8dcSSimon Schubert {
38115796c8dcSSimon Schubert sections[i] = s;
38125796c8dcSSimon Schubert ++i;
3813c50c785cSJohn Marino /* A wrapping section potentially clashes with header. */
3814c50c785cSJohn Marino if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask))
3815c50c785cSJohn Marino wrap_to = (s->lma + s->size) & addr_mask;
38165796c8dcSSimon Schubert }
38175796c8dcSSimon Schubert }
38185796c8dcSSimon Schubert BFD_ASSERT (i <= bfd_count_sections (abfd));
38195796c8dcSSimon Schubert count = i;
38205796c8dcSSimon Schubert
38215796c8dcSSimon Schubert qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);
38225796c8dcSSimon Schubert
38235796c8dcSSimon Schubert /* Build the mapping. */
38245796c8dcSSimon Schubert
38255796c8dcSSimon Schubert mfirst = NULL;
38265796c8dcSSimon Schubert pm = &mfirst;
38275796c8dcSSimon Schubert
38285796c8dcSSimon Schubert /* If we have a .interp section, then create a PT_PHDR segment for
38295796c8dcSSimon Schubert the program headers and a PT_INTERP segment for the .interp
38305796c8dcSSimon Schubert section. */
38315796c8dcSSimon Schubert s = bfd_get_section_by_name (abfd, ".interp");
38325796c8dcSSimon Schubert if (s != NULL && (s->flags & SEC_LOAD) != 0)
38335796c8dcSSimon Schubert {
38345796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
38355796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
38365796c8dcSSimon Schubert if (m == NULL)
38375796c8dcSSimon Schubert goto error_return;
38385796c8dcSSimon Schubert m->next = NULL;
38395796c8dcSSimon Schubert m->p_type = PT_PHDR;
38405796c8dcSSimon Schubert /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */
38415796c8dcSSimon Schubert m->p_flags = PF_R | PF_X;
38425796c8dcSSimon Schubert m->p_flags_valid = 1;
38435796c8dcSSimon Schubert m->includes_phdrs = 1;
38445796c8dcSSimon Schubert
38455796c8dcSSimon Schubert *pm = m;
38465796c8dcSSimon Schubert pm = &m->next;
38475796c8dcSSimon Schubert
38485796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
38495796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
38505796c8dcSSimon Schubert if (m == NULL)
38515796c8dcSSimon Schubert goto error_return;
38525796c8dcSSimon Schubert m->next = NULL;
38535796c8dcSSimon Schubert m->p_type = PT_INTERP;
38545796c8dcSSimon Schubert m->count = 1;
38555796c8dcSSimon Schubert m->sections[0] = s;
38565796c8dcSSimon Schubert
38575796c8dcSSimon Schubert *pm = m;
38585796c8dcSSimon Schubert pm = &m->next;
38595796c8dcSSimon Schubert }
38605796c8dcSSimon Schubert
38615796c8dcSSimon Schubert /* Look through the sections. We put sections in the same program
38625796c8dcSSimon Schubert segment when the start of the second section can be placed within
38635796c8dcSSimon Schubert a few bytes of the end of the first section. */
38645796c8dcSSimon Schubert last_hdr = NULL;
38655796c8dcSSimon Schubert last_size = 0;
38665796c8dcSSimon Schubert phdr_index = 0;
38675796c8dcSSimon Schubert maxpagesize = bed->maxpagesize;
38685796c8dcSSimon Schubert writable = FALSE;
38695796c8dcSSimon Schubert dynsec = bfd_get_section_by_name (abfd, ".dynamic");
38705796c8dcSSimon Schubert if (dynsec != NULL
38715796c8dcSSimon Schubert && (dynsec->flags & SEC_LOAD) == 0)
38725796c8dcSSimon Schubert dynsec = NULL;
38735796c8dcSSimon Schubert
38745796c8dcSSimon Schubert /* Deal with -Ttext or something similar such that the first section
38755796c8dcSSimon Schubert is not adjacent to the program headers. This is an
38765796c8dcSSimon Schubert approximation, since at this point we don't know exactly how many
38775796c8dcSSimon Schubert program headers we will need. */
38785796c8dcSSimon Schubert if (count > 0)
38795796c8dcSSimon Schubert {
3880*ef5ccd6cSJohn Marino bfd_size_type phdr_size = elf_program_header_size (abfd);
38815796c8dcSSimon Schubert
38825796c8dcSSimon Schubert if (phdr_size == (bfd_size_type) -1)
38835796c8dcSSimon Schubert phdr_size = get_program_header_size (abfd, info);
3884*ef5ccd6cSJohn Marino phdr_size += bed->s->sizeof_ehdr;
38855796c8dcSSimon Schubert if ((abfd->flags & D_PAGED) == 0
3886c50c785cSJohn Marino || (sections[0]->lma & addr_mask) < phdr_size
3887c50c785cSJohn Marino || ((sections[0]->lma & addr_mask) % maxpagesize
3888c50c785cSJohn Marino < phdr_size % maxpagesize)
3889c50c785cSJohn Marino || (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to)
38905796c8dcSSimon Schubert phdr_in_segment = FALSE;
38915796c8dcSSimon Schubert }
38925796c8dcSSimon Schubert
38935796c8dcSSimon Schubert for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
38945796c8dcSSimon Schubert {
38955796c8dcSSimon Schubert asection *hdr;
38965796c8dcSSimon Schubert bfd_boolean new_segment;
38975796c8dcSSimon Schubert
38985796c8dcSSimon Schubert hdr = *hdrpp;
38995796c8dcSSimon Schubert
39005796c8dcSSimon Schubert /* See if this section and the last one will fit in the same
39015796c8dcSSimon Schubert segment. */
39025796c8dcSSimon Schubert
39035796c8dcSSimon Schubert if (last_hdr == NULL)
39045796c8dcSSimon Schubert {
39055796c8dcSSimon Schubert /* If we don't have a segment yet, then we don't need a new
39065796c8dcSSimon Schubert one (we build the last one after this loop). */
39075796c8dcSSimon Schubert new_segment = FALSE;
39085796c8dcSSimon Schubert }
39095796c8dcSSimon Schubert else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
39105796c8dcSSimon Schubert {
39115796c8dcSSimon Schubert /* If this section has a different relation between the
39125796c8dcSSimon Schubert virtual address and the load address, then we need a new
39135796c8dcSSimon Schubert segment. */
39145796c8dcSSimon Schubert new_segment = TRUE;
39155796c8dcSSimon Schubert }
3916c50c785cSJohn Marino else if (hdr->lma < last_hdr->lma + last_size
3917c50c785cSJohn Marino || last_hdr->lma + last_size < last_hdr->lma)
3918c50c785cSJohn Marino {
3919c50c785cSJohn Marino /* If this section has a load address that makes it overlap
3920c50c785cSJohn Marino the previous section, then we need a new segment. */
3921c50c785cSJohn Marino new_segment = TRUE;
3922c50c785cSJohn Marino }
39235796c8dcSSimon Schubert /* In the next test we have to be careful when last_hdr->lma is close
39245796c8dcSSimon Schubert to the end of the address space. If the aligned address wraps
39255796c8dcSSimon Schubert around to the start of the address space, then there are no more
39265796c8dcSSimon Schubert pages left in memory and it is OK to assume that the current
39275796c8dcSSimon Schubert section can be included in the current segment. */
39285796c8dcSSimon Schubert else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
39295796c8dcSSimon Schubert > last_hdr->lma)
39305796c8dcSSimon Schubert && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
39315796c8dcSSimon Schubert <= hdr->lma))
39325796c8dcSSimon Schubert {
39335796c8dcSSimon Schubert /* If putting this section in this segment would force us to
39345796c8dcSSimon Schubert skip a page in the segment, then we need a new segment. */
39355796c8dcSSimon Schubert new_segment = TRUE;
39365796c8dcSSimon Schubert }
39375796c8dcSSimon Schubert else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
39385796c8dcSSimon Schubert && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
39395796c8dcSSimon Schubert {
39405796c8dcSSimon Schubert /* We don't want to put a loadable section after a
39415796c8dcSSimon Schubert nonloadable section in the same segment.
39425796c8dcSSimon Schubert Consider .tbss sections as loadable for this purpose. */
39435796c8dcSSimon Schubert new_segment = TRUE;
39445796c8dcSSimon Schubert }
39455796c8dcSSimon Schubert else if ((abfd->flags & D_PAGED) == 0)
39465796c8dcSSimon Schubert {
39475796c8dcSSimon Schubert /* If the file is not demand paged, which means that we
39485796c8dcSSimon Schubert don't require the sections to be correctly aligned in the
39495796c8dcSSimon Schubert file, then there is no other reason for a new segment. */
39505796c8dcSSimon Schubert new_segment = FALSE;
39515796c8dcSSimon Schubert }
39525796c8dcSSimon Schubert else if (! writable
39535796c8dcSSimon Schubert && (hdr->flags & SEC_READONLY) == 0
3954c50c785cSJohn Marino && (((last_hdr->lma + last_size - 1) & -maxpagesize)
3955c50c785cSJohn Marino != (hdr->lma & -maxpagesize)))
39565796c8dcSSimon Schubert {
39575796c8dcSSimon Schubert /* We don't want to put a writable section in a read only
39585796c8dcSSimon Schubert segment, unless they are on the same page in memory
39595796c8dcSSimon Schubert anyhow. We already know that the last section does not
39605796c8dcSSimon Schubert bring us past the current section on the page, so the
39615796c8dcSSimon Schubert only case in which the new section is not on the same
39625796c8dcSSimon Schubert page as the previous section is when the previous section
39635796c8dcSSimon Schubert ends precisely on a page boundary. */
39645796c8dcSSimon Schubert new_segment = TRUE;
39655796c8dcSSimon Schubert }
39665796c8dcSSimon Schubert else
39675796c8dcSSimon Schubert {
39685796c8dcSSimon Schubert /* Otherwise, we can use the same segment. */
39695796c8dcSSimon Schubert new_segment = FALSE;
39705796c8dcSSimon Schubert }
39715796c8dcSSimon Schubert
39725796c8dcSSimon Schubert /* Allow interested parties a chance to override our decision. */
39735796c8dcSSimon Schubert if (last_hdr != NULL
39745796c8dcSSimon Schubert && info != NULL
39755796c8dcSSimon Schubert && info->callbacks->override_segment_assignment != NULL)
39765796c8dcSSimon Schubert new_segment
39775796c8dcSSimon Schubert = info->callbacks->override_segment_assignment (info, abfd, hdr,
39785796c8dcSSimon Schubert last_hdr,
39795796c8dcSSimon Schubert new_segment);
39805796c8dcSSimon Schubert
39815796c8dcSSimon Schubert if (! new_segment)
39825796c8dcSSimon Schubert {
39835796c8dcSSimon Schubert if ((hdr->flags & SEC_READONLY) == 0)
39845796c8dcSSimon Schubert writable = TRUE;
39855796c8dcSSimon Schubert last_hdr = hdr;
39865796c8dcSSimon Schubert /* .tbss sections effectively have zero size. */
39875796c8dcSSimon Schubert if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
39885796c8dcSSimon Schubert != SEC_THREAD_LOCAL)
39895796c8dcSSimon Schubert last_size = hdr->size;
39905796c8dcSSimon Schubert else
39915796c8dcSSimon Schubert last_size = 0;
39925796c8dcSSimon Schubert continue;
39935796c8dcSSimon Schubert }
39945796c8dcSSimon Schubert
39955796c8dcSSimon Schubert /* We need a new program segment. We must create a new program
39965796c8dcSSimon Schubert header holding all the sections from phdr_index until hdr. */
39975796c8dcSSimon Schubert
39985796c8dcSSimon Schubert m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
39995796c8dcSSimon Schubert if (m == NULL)
40005796c8dcSSimon Schubert goto error_return;
40015796c8dcSSimon Schubert
40025796c8dcSSimon Schubert *pm = m;
40035796c8dcSSimon Schubert pm = &m->next;
40045796c8dcSSimon Schubert
40055796c8dcSSimon Schubert if ((hdr->flags & SEC_READONLY) == 0)
40065796c8dcSSimon Schubert writable = TRUE;
40075796c8dcSSimon Schubert else
40085796c8dcSSimon Schubert writable = FALSE;
40095796c8dcSSimon Schubert
40105796c8dcSSimon Schubert last_hdr = hdr;
40115796c8dcSSimon Schubert /* .tbss sections effectively have zero size. */
40125796c8dcSSimon Schubert if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
40135796c8dcSSimon Schubert last_size = hdr->size;
40145796c8dcSSimon Schubert else
40155796c8dcSSimon Schubert last_size = 0;
40165796c8dcSSimon Schubert phdr_index = i;
40175796c8dcSSimon Schubert phdr_in_segment = FALSE;
40185796c8dcSSimon Schubert }
40195796c8dcSSimon Schubert
4020a45ae5f8SJohn Marino /* Create a final PT_LOAD program segment, but not if it's just
4021a45ae5f8SJohn Marino for .tbss. */
4022a45ae5f8SJohn Marino if (last_hdr != NULL
4023a45ae5f8SJohn Marino && (i - phdr_index != 1
4024a45ae5f8SJohn Marino || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
4025a45ae5f8SJohn Marino != SEC_THREAD_LOCAL)))
40265796c8dcSSimon Schubert {
40275796c8dcSSimon Schubert m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
40285796c8dcSSimon Schubert if (m == NULL)
40295796c8dcSSimon Schubert goto error_return;
40305796c8dcSSimon Schubert
40315796c8dcSSimon Schubert *pm = m;
40325796c8dcSSimon Schubert pm = &m->next;
40335796c8dcSSimon Schubert }
40345796c8dcSSimon Schubert
40355796c8dcSSimon Schubert /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */
40365796c8dcSSimon Schubert if (dynsec != NULL)
40375796c8dcSSimon Schubert {
40385796c8dcSSimon Schubert m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
40395796c8dcSSimon Schubert if (m == NULL)
40405796c8dcSSimon Schubert goto error_return;
40415796c8dcSSimon Schubert *pm = m;
40425796c8dcSSimon Schubert pm = &m->next;
40435796c8dcSSimon Schubert }
40445796c8dcSSimon Schubert
40455796c8dcSSimon Schubert /* For each batch of consecutive loadable .note sections,
40465796c8dcSSimon Schubert add a PT_NOTE segment. We don't use bfd_get_section_by_name,
40475796c8dcSSimon Schubert because if we link together nonloadable .note sections and
40485796c8dcSSimon Schubert loadable .note sections, we will generate two .note sections
40495796c8dcSSimon Schubert in the output file. FIXME: Using names for section types is
40505796c8dcSSimon Schubert bogus anyhow. */
40515796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
40525796c8dcSSimon Schubert {
40535796c8dcSSimon Schubert if ((s->flags & SEC_LOAD) != 0
40545796c8dcSSimon Schubert && CONST_STRNEQ (s->name, ".note"))
40555796c8dcSSimon Schubert {
40565796c8dcSSimon Schubert asection *s2;
4057cf7f2e2dSJohn Marino
4058cf7f2e2dSJohn Marino count = 1;
40595796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
40605796c8dcSSimon Schubert if (s->alignment_power == 2)
40615796c8dcSSimon Schubert for (s2 = s; s2->next != NULL; s2 = s2->next)
40625796c8dcSSimon Schubert {
40635796c8dcSSimon Schubert if (s2->next->alignment_power == 2
40645796c8dcSSimon Schubert && (s2->next->flags & SEC_LOAD) != 0
40655796c8dcSSimon Schubert && CONST_STRNEQ (s2->next->name, ".note")
4066c50c785cSJohn Marino && align_power (s2->lma + s2->size, 2)
4067c50c785cSJohn Marino == s2->next->lma)
40685796c8dcSSimon Schubert count++;
40695796c8dcSSimon Schubert else
40705796c8dcSSimon Schubert break;
40715796c8dcSSimon Schubert }
40725796c8dcSSimon Schubert amt += (count - 1) * sizeof (asection *);
40735796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
40745796c8dcSSimon Schubert if (m == NULL)
40755796c8dcSSimon Schubert goto error_return;
40765796c8dcSSimon Schubert m->next = NULL;
40775796c8dcSSimon Schubert m->p_type = PT_NOTE;
40785796c8dcSSimon Schubert m->count = count;
40795796c8dcSSimon Schubert while (count > 1)
40805796c8dcSSimon Schubert {
40815796c8dcSSimon Schubert m->sections[m->count - count--] = s;
40825796c8dcSSimon Schubert BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
40835796c8dcSSimon Schubert s = s->next;
40845796c8dcSSimon Schubert }
40855796c8dcSSimon Schubert m->sections[m->count - 1] = s;
40865796c8dcSSimon Schubert BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
40875796c8dcSSimon Schubert *pm = m;
40885796c8dcSSimon Schubert pm = &m->next;
40895796c8dcSSimon Schubert }
40905796c8dcSSimon Schubert if (s->flags & SEC_THREAD_LOCAL)
40915796c8dcSSimon Schubert {
40925796c8dcSSimon Schubert if (! tls_count)
40935796c8dcSSimon Schubert first_tls = s;
40945796c8dcSSimon Schubert tls_count++;
40955796c8dcSSimon Schubert }
40965796c8dcSSimon Schubert }
40975796c8dcSSimon Schubert
40985796c8dcSSimon Schubert /* If there are any SHF_TLS output sections, add PT_TLS segment. */
40995796c8dcSSimon Schubert if (tls_count > 0)
41005796c8dcSSimon Schubert {
41015796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
41025796c8dcSSimon Schubert amt += (tls_count - 1) * sizeof (asection *);
41035796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41045796c8dcSSimon Schubert if (m == NULL)
41055796c8dcSSimon Schubert goto error_return;
41065796c8dcSSimon Schubert m->next = NULL;
41075796c8dcSSimon Schubert m->p_type = PT_TLS;
41085796c8dcSSimon Schubert m->count = tls_count;
41095796c8dcSSimon Schubert /* Mandated PF_R. */
41105796c8dcSSimon Schubert m->p_flags = PF_R;
41115796c8dcSSimon Schubert m->p_flags_valid = 1;
4112cf7f2e2dSJohn Marino for (i = 0; i < (unsigned int) tls_count; ++i)
41135796c8dcSSimon Schubert {
41145796c8dcSSimon Schubert BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
41155796c8dcSSimon Schubert m->sections[i] = first_tls;
41165796c8dcSSimon Schubert first_tls = first_tls->next;
41175796c8dcSSimon Schubert }
41185796c8dcSSimon Schubert
41195796c8dcSSimon Schubert *pm = m;
41205796c8dcSSimon Schubert pm = &m->next;
41215796c8dcSSimon Schubert }
41225796c8dcSSimon Schubert
41235796c8dcSSimon Schubert /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
41245796c8dcSSimon Schubert segment. */
4125*ef5ccd6cSJohn Marino eh_frame_hdr = elf_eh_frame_hdr (abfd);
41265796c8dcSSimon Schubert if (eh_frame_hdr != NULL
41275796c8dcSSimon Schubert && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
41285796c8dcSSimon Schubert {
41295796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
41305796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41315796c8dcSSimon Schubert if (m == NULL)
41325796c8dcSSimon Schubert goto error_return;
41335796c8dcSSimon Schubert m->next = NULL;
41345796c8dcSSimon Schubert m->p_type = PT_GNU_EH_FRAME;
41355796c8dcSSimon Schubert m->count = 1;
41365796c8dcSSimon Schubert m->sections[0] = eh_frame_hdr->output_section;
41375796c8dcSSimon Schubert
41385796c8dcSSimon Schubert *pm = m;
41395796c8dcSSimon Schubert pm = &m->next;
41405796c8dcSSimon Schubert }
41415796c8dcSSimon Schubert
4142*ef5ccd6cSJohn Marino if (elf_stack_flags (abfd))
41435796c8dcSSimon Schubert {
41445796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
41455796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41465796c8dcSSimon Schubert if (m == NULL)
41475796c8dcSSimon Schubert goto error_return;
41485796c8dcSSimon Schubert m->next = NULL;
41495796c8dcSSimon Schubert m->p_type = PT_GNU_STACK;
4150*ef5ccd6cSJohn Marino m->p_flags = elf_stack_flags (abfd);
4151*ef5ccd6cSJohn Marino m->p_align = bed->stack_align;
41525796c8dcSSimon Schubert m->p_flags_valid = 1;
4153*ef5ccd6cSJohn Marino m->p_align_valid = m->p_align != 0;
4154*ef5ccd6cSJohn Marino if (info->stacksize > 0)
4155*ef5ccd6cSJohn Marino {
4156*ef5ccd6cSJohn Marino m->p_size = info->stacksize;
4157*ef5ccd6cSJohn Marino m->p_size_valid = 1;
4158*ef5ccd6cSJohn Marino }
41595796c8dcSSimon Schubert
41605796c8dcSSimon Schubert *pm = m;
41615796c8dcSSimon Schubert pm = &m->next;
41625796c8dcSSimon Schubert }
41635796c8dcSSimon Schubert
41645796c8dcSSimon Schubert if (info != NULL && info->relro)
41655796c8dcSSimon Schubert {
41665796c8dcSSimon Schubert for (m = mfirst; m != NULL; m = m->next)
41675796c8dcSSimon Schubert {
4168*ef5ccd6cSJohn Marino if (m->p_type == PT_LOAD
4169*ef5ccd6cSJohn Marino && m->count != 0
4170*ef5ccd6cSJohn Marino && m->sections[0]->vma >= info->relro_start
4171*ef5ccd6cSJohn Marino && m->sections[0]->vma < info->relro_end)
41725796c8dcSSimon Schubert {
4173*ef5ccd6cSJohn Marino i = m->count;
4174*ef5ccd6cSJohn Marino while (--i != (unsigned) -1)
4175*ef5ccd6cSJohn Marino if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS))
4176*ef5ccd6cSJohn Marino == (SEC_LOAD | SEC_HAS_CONTENTS))
4177*ef5ccd6cSJohn Marino break;
41785796c8dcSSimon Schubert
4179*ef5ccd6cSJohn Marino if (i == (unsigned) -1)
4180*ef5ccd6cSJohn Marino continue;
4181*ef5ccd6cSJohn Marino
4182*ef5ccd6cSJohn Marino if (m->sections[i]->vma + m->sections[i]->size
4183*ef5ccd6cSJohn Marino >= info->relro_end)
41845796c8dcSSimon Schubert break;
41855796c8dcSSimon Schubert }
41865796c8dcSSimon Schubert }
41875796c8dcSSimon Schubert
41885796c8dcSSimon Schubert /* Make a PT_GNU_RELRO segment only when it isn't empty. */
41895796c8dcSSimon Schubert if (m != NULL)
41905796c8dcSSimon Schubert {
41915796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
41925796c8dcSSimon Schubert m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41935796c8dcSSimon Schubert if (m == NULL)
41945796c8dcSSimon Schubert goto error_return;
41955796c8dcSSimon Schubert m->next = NULL;
41965796c8dcSSimon Schubert m->p_type = PT_GNU_RELRO;
41975796c8dcSSimon Schubert m->p_flags = PF_R;
41985796c8dcSSimon Schubert m->p_flags_valid = 1;
41995796c8dcSSimon Schubert
42005796c8dcSSimon Schubert *pm = m;
42015796c8dcSSimon Schubert pm = &m->next;
42025796c8dcSSimon Schubert }
42035796c8dcSSimon Schubert }
42045796c8dcSSimon Schubert
42055796c8dcSSimon Schubert free (sections);
4206*ef5ccd6cSJohn Marino elf_seg_map (abfd) = mfirst;
42075796c8dcSSimon Schubert }
42085796c8dcSSimon Schubert
42095796c8dcSSimon Schubert if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
42105796c8dcSSimon Schubert return FALSE;
42115796c8dcSSimon Schubert
4212*ef5ccd6cSJohn Marino for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
42135796c8dcSSimon Schubert ++count;
4214*ef5ccd6cSJohn Marino elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;
42155796c8dcSSimon Schubert
42165796c8dcSSimon Schubert return TRUE;
42175796c8dcSSimon Schubert
42185796c8dcSSimon Schubert error_return:
42195796c8dcSSimon Schubert if (sections != NULL)
42205796c8dcSSimon Schubert free (sections);
42215796c8dcSSimon Schubert return FALSE;
42225796c8dcSSimon Schubert }
42235796c8dcSSimon Schubert
42245796c8dcSSimon Schubert /* Sort sections by address. */
42255796c8dcSSimon Schubert
42265796c8dcSSimon Schubert static int
elf_sort_sections(const void * arg1,const void * arg2)42275796c8dcSSimon Schubert elf_sort_sections (const void *arg1, const void *arg2)
42285796c8dcSSimon Schubert {
42295796c8dcSSimon Schubert const asection *sec1 = *(const asection **) arg1;
42305796c8dcSSimon Schubert const asection *sec2 = *(const asection **) arg2;
42315796c8dcSSimon Schubert bfd_size_type size1, size2;
42325796c8dcSSimon Schubert
42335796c8dcSSimon Schubert /* Sort by LMA first, since this is the address used to
42345796c8dcSSimon Schubert place the section into a segment. */
42355796c8dcSSimon Schubert if (sec1->lma < sec2->lma)
42365796c8dcSSimon Schubert return -1;
42375796c8dcSSimon Schubert else if (sec1->lma > sec2->lma)
42385796c8dcSSimon Schubert return 1;
42395796c8dcSSimon Schubert
42405796c8dcSSimon Schubert /* Then sort by VMA. Normally the LMA and the VMA will be
42415796c8dcSSimon Schubert the same, and this will do nothing. */
42425796c8dcSSimon Schubert if (sec1->vma < sec2->vma)
42435796c8dcSSimon Schubert return -1;
42445796c8dcSSimon Schubert else if (sec1->vma > sec2->vma)
42455796c8dcSSimon Schubert return 1;
42465796c8dcSSimon Schubert
42475796c8dcSSimon Schubert /* Put !SEC_LOAD sections after SEC_LOAD ones. */
42485796c8dcSSimon Schubert
42495796c8dcSSimon Schubert #define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
42505796c8dcSSimon Schubert
42515796c8dcSSimon Schubert if (TOEND (sec1))
42525796c8dcSSimon Schubert {
42535796c8dcSSimon Schubert if (TOEND (sec2))
42545796c8dcSSimon Schubert {
42555796c8dcSSimon Schubert /* If the indicies are the same, do not return 0
42565796c8dcSSimon Schubert here, but continue to try the next comparison. */
42575796c8dcSSimon Schubert if (sec1->target_index - sec2->target_index != 0)
42585796c8dcSSimon Schubert return sec1->target_index - sec2->target_index;
42595796c8dcSSimon Schubert }
42605796c8dcSSimon Schubert else
42615796c8dcSSimon Schubert return 1;
42625796c8dcSSimon Schubert }
42635796c8dcSSimon Schubert else if (TOEND (sec2))
42645796c8dcSSimon Schubert return -1;
42655796c8dcSSimon Schubert
42665796c8dcSSimon Schubert #undef TOEND
42675796c8dcSSimon Schubert
42685796c8dcSSimon Schubert /* Sort by size, to put zero sized sections
42695796c8dcSSimon Schubert before others at the same address. */
42705796c8dcSSimon Schubert
42715796c8dcSSimon Schubert size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
42725796c8dcSSimon Schubert size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;
42735796c8dcSSimon Schubert
42745796c8dcSSimon Schubert if (size1 < size2)
42755796c8dcSSimon Schubert return -1;
42765796c8dcSSimon Schubert if (size1 > size2)
42775796c8dcSSimon Schubert return 1;
42785796c8dcSSimon Schubert
42795796c8dcSSimon Schubert return sec1->target_index - sec2->target_index;
42805796c8dcSSimon Schubert }
42815796c8dcSSimon Schubert
42825796c8dcSSimon Schubert /* Ian Lance Taylor writes:
42835796c8dcSSimon Schubert
42845796c8dcSSimon Schubert We shouldn't be using % with a negative signed number. That's just
42855796c8dcSSimon Schubert not good. We have to make sure either that the number is not
42865796c8dcSSimon Schubert negative, or that the number has an unsigned type. When the types
42875796c8dcSSimon Schubert are all the same size they wind up as unsigned. When file_ptr is a
42885796c8dcSSimon Schubert larger signed type, the arithmetic winds up as signed long long,
42895796c8dcSSimon Schubert which is wrong.
42905796c8dcSSimon Schubert
42915796c8dcSSimon Schubert What we're trying to say here is something like ``increase OFF by
42925796c8dcSSimon Schubert the least amount that will cause it to be equal to the VMA modulo
42935796c8dcSSimon Schubert the page size.'' */
42945796c8dcSSimon Schubert /* In other words, something like:
42955796c8dcSSimon Schubert
42965796c8dcSSimon Schubert vma_offset = m->sections[0]->vma % bed->maxpagesize;
42975796c8dcSSimon Schubert off_offset = off % bed->maxpagesize;
42985796c8dcSSimon Schubert if (vma_offset < off_offset)
42995796c8dcSSimon Schubert adjustment = vma_offset + bed->maxpagesize - off_offset;
43005796c8dcSSimon Schubert else
43015796c8dcSSimon Schubert adjustment = vma_offset - off_offset;
43025796c8dcSSimon Schubert
43035796c8dcSSimon Schubert which can can be collapsed into the expression below. */
43045796c8dcSSimon Schubert
43055796c8dcSSimon Schubert static file_ptr
vma_page_aligned_bias(bfd_vma vma,ufile_ptr off,bfd_vma maxpagesize)43065796c8dcSSimon Schubert vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
43075796c8dcSSimon Schubert {
43085796c8dcSSimon Schubert return ((vma - off) % maxpagesize);
43095796c8dcSSimon Schubert }
43105796c8dcSSimon Schubert
43115796c8dcSSimon Schubert static void
print_segment_map(const struct elf_segment_map * m)43125796c8dcSSimon Schubert print_segment_map (const struct elf_segment_map *m)
43135796c8dcSSimon Schubert {
43145796c8dcSSimon Schubert unsigned int j;
43155796c8dcSSimon Schubert const char *pt = get_segment_type (m->p_type);
43165796c8dcSSimon Schubert char buf[32];
43175796c8dcSSimon Schubert
43185796c8dcSSimon Schubert if (pt == NULL)
43195796c8dcSSimon Schubert {
43205796c8dcSSimon Schubert if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC)
43215796c8dcSSimon Schubert sprintf (buf, "LOPROC+%7.7x",
43225796c8dcSSimon Schubert (unsigned int) (m->p_type - PT_LOPROC));
43235796c8dcSSimon Schubert else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS)
43245796c8dcSSimon Schubert sprintf (buf, "LOOS+%7.7x",
43255796c8dcSSimon Schubert (unsigned int) (m->p_type - PT_LOOS));
43265796c8dcSSimon Schubert else
43275796c8dcSSimon Schubert snprintf (buf, sizeof (buf), "%8.8x",
43285796c8dcSSimon Schubert (unsigned int) m->p_type);
43295796c8dcSSimon Schubert pt = buf;
43305796c8dcSSimon Schubert }
4331c50c785cSJohn Marino fflush (stdout);
43325796c8dcSSimon Schubert fprintf (stderr, "%s:", pt);
43335796c8dcSSimon Schubert for (j = 0; j < m->count; j++)
43345796c8dcSSimon Schubert fprintf (stderr, " %s", m->sections [j]->name);
43355796c8dcSSimon Schubert putc ('\n',stderr);
4336c50c785cSJohn Marino fflush (stderr);
43375796c8dcSSimon Schubert }
43385796c8dcSSimon Schubert
4339cf7f2e2dSJohn Marino static bfd_boolean
write_zeros(bfd * abfd,file_ptr pos,bfd_size_type len)4340cf7f2e2dSJohn Marino write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len)
4341cf7f2e2dSJohn Marino {
4342cf7f2e2dSJohn Marino void *buf;
4343cf7f2e2dSJohn Marino bfd_boolean ret;
4344cf7f2e2dSJohn Marino
4345cf7f2e2dSJohn Marino if (bfd_seek (abfd, pos, SEEK_SET) != 0)
4346cf7f2e2dSJohn Marino return FALSE;
4347cf7f2e2dSJohn Marino buf = bfd_zmalloc (len);
4348cf7f2e2dSJohn Marino if (buf == NULL)
4349cf7f2e2dSJohn Marino return FALSE;
4350cf7f2e2dSJohn Marino ret = bfd_bwrite (buf, len, abfd) == len;
4351cf7f2e2dSJohn Marino free (buf);
4352cf7f2e2dSJohn Marino return ret;
4353cf7f2e2dSJohn Marino }
4354cf7f2e2dSJohn Marino
43555796c8dcSSimon Schubert /* Assign file positions to the sections based on the mapping from
43565796c8dcSSimon Schubert sections to segments. This function also sets up some fields in
43575796c8dcSSimon Schubert the file header. */
43585796c8dcSSimon Schubert
43595796c8dcSSimon Schubert static bfd_boolean
assign_file_positions_for_load_sections(bfd * abfd,struct bfd_link_info * link_info)43605796c8dcSSimon Schubert assign_file_positions_for_load_sections (bfd *abfd,
43615796c8dcSSimon Schubert struct bfd_link_info *link_info)
43625796c8dcSSimon Schubert {
43635796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
43645796c8dcSSimon Schubert struct elf_segment_map *m;
43655796c8dcSSimon Schubert Elf_Internal_Phdr *phdrs;
43665796c8dcSSimon Schubert Elf_Internal_Phdr *p;
43675796c8dcSSimon Schubert file_ptr off;
43685796c8dcSSimon Schubert bfd_size_type maxpagesize;
43695796c8dcSSimon Schubert unsigned int alloc;
43705796c8dcSSimon Schubert unsigned int i, j;
43715796c8dcSSimon Schubert bfd_vma header_pad = 0;
43725796c8dcSSimon Schubert
43735796c8dcSSimon Schubert if (link_info == NULL
43745796c8dcSSimon Schubert && !_bfd_elf_map_sections_to_segments (abfd, link_info))
43755796c8dcSSimon Schubert return FALSE;
43765796c8dcSSimon Schubert
43775796c8dcSSimon Schubert alloc = 0;
4378*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd); m != NULL; m = m->next)
43795796c8dcSSimon Schubert {
43805796c8dcSSimon Schubert ++alloc;
43815796c8dcSSimon Schubert if (m->header_size)
43825796c8dcSSimon Schubert header_pad = m->header_size;
43835796c8dcSSimon Schubert }
43845796c8dcSSimon Schubert
4385c50c785cSJohn Marino if (alloc)
4386c50c785cSJohn Marino {
43875796c8dcSSimon Schubert elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
43885796c8dcSSimon Schubert elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
4389c50c785cSJohn Marino }
4390c50c785cSJohn Marino else
4391c50c785cSJohn Marino {
4392c50c785cSJohn Marino /* PR binutils/12467. */
4393c50c785cSJohn Marino elf_elfheader (abfd)->e_phoff = 0;
4394c50c785cSJohn Marino elf_elfheader (abfd)->e_phentsize = 0;
4395c50c785cSJohn Marino }
4396c50c785cSJohn Marino
43975796c8dcSSimon Schubert elf_elfheader (abfd)->e_phnum = alloc;
43985796c8dcSSimon Schubert
4399*ef5ccd6cSJohn Marino if (elf_program_header_size (abfd) == (bfd_size_type) -1)
4400*ef5ccd6cSJohn Marino elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr;
44015796c8dcSSimon Schubert else
4402*ef5ccd6cSJohn Marino BFD_ASSERT (elf_program_header_size (abfd)
44035796c8dcSSimon Schubert >= alloc * bed->s->sizeof_phdr);
44045796c8dcSSimon Schubert
44055796c8dcSSimon Schubert if (alloc == 0)
44065796c8dcSSimon Schubert {
4407*ef5ccd6cSJohn Marino elf_next_file_pos (abfd) = bed->s->sizeof_ehdr;
44085796c8dcSSimon Schubert return TRUE;
44095796c8dcSSimon Schubert }
44105796c8dcSSimon Schubert
4411*ef5ccd6cSJohn Marino /* We're writing the size in elf_program_header_size (abfd),
44125796c8dcSSimon Schubert see assign_file_positions_except_relocs, so make sure we have
44135796c8dcSSimon Schubert that amount allocated, with trailing space cleared.
4414*ef5ccd6cSJohn Marino The variable alloc contains the computed need, while
4415*ef5ccd6cSJohn Marino elf_program_header_size (abfd) contains the size used for the
44165796c8dcSSimon Schubert layout.
44175796c8dcSSimon Schubert See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
44185796c8dcSSimon Schubert where the layout is forced to according to a larger size in the
44195796c8dcSSimon Schubert last iterations for the testcase ld-elf/header. */
4420*ef5ccd6cSJohn Marino BFD_ASSERT (elf_program_header_size (abfd) % bed->s->sizeof_phdr
44215796c8dcSSimon Schubert == 0);
44225796c8dcSSimon Schubert phdrs = (Elf_Internal_Phdr *)
44235796c8dcSSimon Schubert bfd_zalloc2 (abfd,
4424*ef5ccd6cSJohn Marino (elf_program_header_size (abfd) / bed->s->sizeof_phdr),
44255796c8dcSSimon Schubert sizeof (Elf_Internal_Phdr));
44265796c8dcSSimon Schubert elf_tdata (abfd)->phdr = phdrs;
44275796c8dcSSimon Schubert if (phdrs == NULL)
44285796c8dcSSimon Schubert return FALSE;
44295796c8dcSSimon Schubert
44305796c8dcSSimon Schubert maxpagesize = 1;
44315796c8dcSSimon Schubert if ((abfd->flags & D_PAGED) != 0)
44325796c8dcSSimon Schubert maxpagesize = bed->maxpagesize;
44335796c8dcSSimon Schubert
44345796c8dcSSimon Schubert off = bed->s->sizeof_ehdr;
44355796c8dcSSimon Schubert off += alloc * bed->s->sizeof_phdr;
44365796c8dcSSimon Schubert if (header_pad < (bfd_vma) off)
44375796c8dcSSimon Schubert header_pad = 0;
44385796c8dcSSimon Schubert else
44395796c8dcSSimon Schubert header_pad -= off;
44405796c8dcSSimon Schubert off += header_pad;
44415796c8dcSSimon Schubert
4442*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd), p = phdrs, j = 0;
44435796c8dcSSimon Schubert m != NULL;
44445796c8dcSSimon Schubert m = m->next, p++, j++)
44455796c8dcSSimon Schubert {
44465796c8dcSSimon Schubert asection **secpp;
44475796c8dcSSimon Schubert bfd_vma off_adjust;
44485796c8dcSSimon Schubert bfd_boolean no_contents;
44495796c8dcSSimon Schubert
44505796c8dcSSimon Schubert /* If elf_segment_map is not from map_sections_to_segments, the
44515796c8dcSSimon Schubert sections may not be correctly ordered. NOTE: sorting should
44525796c8dcSSimon Schubert not be done to the PT_NOTE section of a corefile, which may
44535796c8dcSSimon Schubert contain several pseudo-sections artificially created by bfd.
44545796c8dcSSimon Schubert Sorting these pseudo-sections breaks things badly. */
44555796c8dcSSimon Schubert if (m->count > 1
44565796c8dcSSimon Schubert && !(elf_elfheader (abfd)->e_type == ET_CORE
44575796c8dcSSimon Schubert && m->p_type == PT_NOTE))
44585796c8dcSSimon Schubert qsort (m->sections, (size_t) m->count, sizeof (asection *),
44595796c8dcSSimon Schubert elf_sort_sections);
44605796c8dcSSimon Schubert
44615796c8dcSSimon Schubert /* An ELF segment (described by Elf_Internal_Phdr) may contain a
44625796c8dcSSimon Schubert number of sections with contents contributing to both p_filesz
44635796c8dcSSimon Schubert and p_memsz, followed by a number of sections with no contents
44645796c8dcSSimon Schubert that just contribute to p_memsz. In this loop, OFF tracks next
44655796c8dcSSimon Schubert available file offset for PT_LOAD and PT_NOTE segments. */
44665796c8dcSSimon Schubert p->p_type = m->p_type;
44675796c8dcSSimon Schubert p->p_flags = m->p_flags;
44685796c8dcSSimon Schubert
44695796c8dcSSimon Schubert if (m->count == 0)
44705796c8dcSSimon Schubert p->p_vaddr = 0;
44715796c8dcSSimon Schubert else
44725796c8dcSSimon Schubert p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset;
44735796c8dcSSimon Schubert
44745796c8dcSSimon Schubert if (m->p_paddr_valid)
44755796c8dcSSimon Schubert p->p_paddr = m->p_paddr;
44765796c8dcSSimon Schubert else if (m->count == 0)
44775796c8dcSSimon Schubert p->p_paddr = 0;
44785796c8dcSSimon Schubert else
44795796c8dcSSimon Schubert p->p_paddr = m->sections[0]->lma - m->p_vaddr_offset;
44805796c8dcSSimon Schubert
44815796c8dcSSimon Schubert if (p->p_type == PT_LOAD
44825796c8dcSSimon Schubert && (abfd->flags & D_PAGED) != 0)
44835796c8dcSSimon Schubert {
44845796c8dcSSimon Schubert /* p_align in demand paged PT_LOAD segments effectively stores
44855796c8dcSSimon Schubert the maximum page size. When copying an executable with
44865796c8dcSSimon Schubert objcopy, we set m->p_align from the input file. Use this
44875796c8dcSSimon Schubert value for maxpagesize rather than bed->maxpagesize, which
44885796c8dcSSimon Schubert may be different. Note that we use maxpagesize for PT_TLS
44895796c8dcSSimon Schubert segment alignment later in this function, so we are relying
44905796c8dcSSimon Schubert on at least one PT_LOAD segment appearing before a PT_TLS
44915796c8dcSSimon Schubert segment. */
44925796c8dcSSimon Schubert if (m->p_align_valid)
44935796c8dcSSimon Schubert maxpagesize = m->p_align;
44945796c8dcSSimon Schubert
44955796c8dcSSimon Schubert p->p_align = maxpagesize;
44965796c8dcSSimon Schubert }
44975796c8dcSSimon Schubert else if (m->p_align_valid)
44985796c8dcSSimon Schubert p->p_align = m->p_align;
44995796c8dcSSimon Schubert else if (m->count == 0)
45005796c8dcSSimon Schubert p->p_align = 1 << bed->s->log_file_align;
45015796c8dcSSimon Schubert else
45025796c8dcSSimon Schubert p->p_align = 0;
45035796c8dcSSimon Schubert
45045796c8dcSSimon Schubert no_contents = FALSE;
45055796c8dcSSimon Schubert off_adjust = 0;
45065796c8dcSSimon Schubert if (p->p_type == PT_LOAD
45075796c8dcSSimon Schubert && m->count > 0)
45085796c8dcSSimon Schubert {
45095796c8dcSSimon Schubert bfd_size_type align;
45105796c8dcSSimon Schubert unsigned int align_power = 0;
45115796c8dcSSimon Schubert
45125796c8dcSSimon Schubert if (m->p_align_valid)
45135796c8dcSSimon Schubert align = p->p_align;
45145796c8dcSSimon Schubert else
45155796c8dcSSimon Schubert {
45165796c8dcSSimon Schubert for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
45175796c8dcSSimon Schubert {
45185796c8dcSSimon Schubert unsigned int secalign;
45195796c8dcSSimon Schubert
45205796c8dcSSimon Schubert secalign = bfd_get_section_alignment (abfd, *secpp);
45215796c8dcSSimon Schubert if (secalign > align_power)
45225796c8dcSSimon Schubert align_power = secalign;
45235796c8dcSSimon Schubert }
45245796c8dcSSimon Schubert align = (bfd_size_type) 1 << align_power;
45255796c8dcSSimon Schubert if (align < maxpagesize)
45265796c8dcSSimon Schubert align = maxpagesize;
45275796c8dcSSimon Schubert }
45285796c8dcSSimon Schubert
45295796c8dcSSimon Schubert for (i = 0; i < m->count; i++)
45305796c8dcSSimon Schubert if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
45315796c8dcSSimon Schubert /* If we aren't making room for this section, then
45325796c8dcSSimon Schubert it must be SHT_NOBITS regardless of what we've
45335796c8dcSSimon Schubert set via struct bfd_elf_special_section. */
45345796c8dcSSimon Schubert elf_section_type (m->sections[i]) = SHT_NOBITS;
45355796c8dcSSimon Schubert
45365796c8dcSSimon Schubert /* Find out whether this segment contains any loadable
45375796c8dcSSimon Schubert sections. */
45385796c8dcSSimon Schubert no_contents = TRUE;
45395796c8dcSSimon Schubert for (i = 0; i < m->count; i++)
45405796c8dcSSimon Schubert if (elf_section_type (m->sections[i]) != SHT_NOBITS)
45415796c8dcSSimon Schubert {
45425796c8dcSSimon Schubert no_contents = FALSE;
45435796c8dcSSimon Schubert break;
45445796c8dcSSimon Schubert }
45455796c8dcSSimon Schubert
4546c50c785cSJohn Marino off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align);
45475796c8dcSSimon Schubert off += off_adjust;
45485796c8dcSSimon Schubert if (no_contents)
45495796c8dcSSimon Schubert {
45505796c8dcSSimon Schubert /* We shouldn't need to align the segment on disk since
45515796c8dcSSimon Schubert the segment doesn't need file space, but the gABI
45525796c8dcSSimon Schubert arguably requires the alignment and glibc ld.so
45535796c8dcSSimon Schubert checks it. So to comply with the alignment
45545796c8dcSSimon Schubert requirement but not waste file space, we adjust
45555796c8dcSSimon Schubert p_offset for just this segment. (OFF_ADJUST is
45565796c8dcSSimon Schubert subtracted from OFF later.) This may put p_offset
45575796c8dcSSimon Schubert past the end of file, but that shouldn't matter. */
45585796c8dcSSimon Schubert }
45595796c8dcSSimon Schubert else
45605796c8dcSSimon Schubert off_adjust = 0;
45615796c8dcSSimon Schubert }
45625796c8dcSSimon Schubert /* Make sure the .dynamic section is the first section in the
45635796c8dcSSimon Schubert PT_DYNAMIC segment. */
45645796c8dcSSimon Schubert else if (p->p_type == PT_DYNAMIC
45655796c8dcSSimon Schubert && m->count > 1
45665796c8dcSSimon Schubert && strcmp (m->sections[0]->name, ".dynamic") != 0)
45675796c8dcSSimon Schubert {
45685796c8dcSSimon Schubert _bfd_error_handler
45695796c8dcSSimon Schubert (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
45705796c8dcSSimon Schubert abfd);
45715796c8dcSSimon Schubert bfd_set_error (bfd_error_bad_value);
45725796c8dcSSimon Schubert return FALSE;
45735796c8dcSSimon Schubert }
45745796c8dcSSimon Schubert /* Set the note section type to SHT_NOTE. */
45755796c8dcSSimon Schubert else if (p->p_type == PT_NOTE)
45765796c8dcSSimon Schubert for (i = 0; i < m->count; i++)
45775796c8dcSSimon Schubert elf_section_type (m->sections[i]) = SHT_NOTE;
45785796c8dcSSimon Schubert
45795796c8dcSSimon Schubert p->p_offset = 0;
45805796c8dcSSimon Schubert p->p_filesz = 0;
45815796c8dcSSimon Schubert p->p_memsz = 0;
45825796c8dcSSimon Schubert
45835796c8dcSSimon Schubert if (m->includes_filehdr)
45845796c8dcSSimon Schubert {
45855796c8dcSSimon Schubert if (!m->p_flags_valid)
45865796c8dcSSimon Schubert p->p_flags |= PF_R;
45875796c8dcSSimon Schubert p->p_filesz = bed->s->sizeof_ehdr;
45885796c8dcSSimon Schubert p->p_memsz = bed->s->sizeof_ehdr;
45895796c8dcSSimon Schubert if (m->count > 0)
45905796c8dcSSimon Schubert {
45915796c8dcSSimon Schubert if (p->p_vaddr < (bfd_vma) off)
45925796c8dcSSimon Schubert {
45935796c8dcSSimon Schubert (*_bfd_error_handler)
45945796c8dcSSimon Schubert (_("%B: Not enough room for program headers, try linking with -N"),
45955796c8dcSSimon Schubert abfd);
45965796c8dcSSimon Schubert bfd_set_error (bfd_error_bad_value);
45975796c8dcSSimon Schubert return FALSE;
45985796c8dcSSimon Schubert }
45995796c8dcSSimon Schubert
46005796c8dcSSimon Schubert p->p_vaddr -= off;
46015796c8dcSSimon Schubert if (!m->p_paddr_valid)
46025796c8dcSSimon Schubert p->p_paddr -= off;
46035796c8dcSSimon Schubert }
46045796c8dcSSimon Schubert }
46055796c8dcSSimon Schubert
46065796c8dcSSimon Schubert if (m->includes_phdrs)
46075796c8dcSSimon Schubert {
46085796c8dcSSimon Schubert if (!m->p_flags_valid)
46095796c8dcSSimon Schubert p->p_flags |= PF_R;
46105796c8dcSSimon Schubert
46115796c8dcSSimon Schubert if (!m->includes_filehdr)
46125796c8dcSSimon Schubert {
46135796c8dcSSimon Schubert p->p_offset = bed->s->sizeof_ehdr;
46145796c8dcSSimon Schubert
46155796c8dcSSimon Schubert if (m->count > 0)
46165796c8dcSSimon Schubert {
46175796c8dcSSimon Schubert p->p_vaddr -= off - p->p_offset;
46185796c8dcSSimon Schubert if (!m->p_paddr_valid)
46195796c8dcSSimon Schubert p->p_paddr -= off - p->p_offset;
46205796c8dcSSimon Schubert }
46215796c8dcSSimon Schubert }
46225796c8dcSSimon Schubert
46235796c8dcSSimon Schubert p->p_filesz += alloc * bed->s->sizeof_phdr;
46245796c8dcSSimon Schubert p->p_memsz += alloc * bed->s->sizeof_phdr;
46255796c8dcSSimon Schubert if (m->count)
46265796c8dcSSimon Schubert {
46275796c8dcSSimon Schubert p->p_filesz += header_pad;
46285796c8dcSSimon Schubert p->p_memsz += header_pad;
46295796c8dcSSimon Schubert }
46305796c8dcSSimon Schubert }
46315796c8dcSSimon Schubert
46325796c8dcSSimon Schubert if (p->p_type == PT_LOAD
46335796c8dcSSimon Schubert || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
46345796c8dcSSimon Schubert {
46355796c8dcSSimon Schubert if (!m->includes_filehdr && !m->includes_phdrs)
46365796c8dcSSimon Schubert p->p_offset = off;
46375796c8dcSSimon Schubert else
46385796c8dcSSimon Schubert {
46395796c8dcSSimon Schubert file_ptr adjust;
46405796c8dcSSimon Schubert
46415796c8dcSSimon Schubert adjust = off - (p->p_offset + p->p_filesz);
46425796c8dcSSimon Schubert if (!no_contents)
46435796c8dcSSimon Schubert p->p_filesz += adjust;
46445796c8dcSSimon Schubert p->p_memsz += adjust;
46455796c8dcSSimon Schubert }
46465796c8dcSSimon Schubert }
46475796c8dcSSimon Schubert
46485796c8dcSSimon Schubert /* Set up p_filesz, p_memsz, p_align and p_flags from the section
46495796c8dcSSimon Schubert maps. Set filepos for sections in PT_LOAD segments, and in
46505796c8dcSSimon Schubert core files, for sections in PT_NOTE segments.
46515796c8dcSSimon Schubert assign_file_positions_for_non_load_sections will set filepos
46525796c8dcSSimon Schubert for other sections and update p_filesz for other segments. */
46535796c8dcSSimon Schubert for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
46545796c8dcSSimon Schubert {
46555796c8dcSSimon Schubert asection *sec;
46565796c8dcSSimon Schubert bfd_size_type align;
46575796c8dcSSimon Schubert Elf_Internal_Shdr *this_hdr;
46585796c8dcSSimon Schubert
46595796c8dcSSimon Schubert sec = *secpp;
46605796c8dcSSimon Schubert this_hdr = &elf_section_data (sec)->this_hdr;
46615796c8dcSSimon Schubert align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
46625796c8dcSSimon Schubert
46635796c8dcSSimon Schubert if ((p->p_type == PT_LOAD
46645796c8dcSSimon Schubert || p->p_type == PT_TLS)
46655796c8dcSSimon Schubert && (this_hdr->sh_type != SHT_NOBITS
46665796c8dcSSimon Schubert || ((this_hdr->sh_flags & SHF_ALLOC) != 0
46675796c8dcSSimon Schubert && ((this_hdr->sh_flags & SHF_TLS) == 0
46685796c8dcSSimon Schubert || p->p_type == PT_TLS))))
46695796c8dcSSimon Schubert {
4670c50c785cSJohn Marino bfd_vma p_start = p->p_paddr;
4671c50c785cSJohn Marino bfd_vma p_end = p_start + p->p_memsz;
4672c50c785cSJohn Marino bfd_vma s_start = sec->lma;
4673c50c785cSJohn Marino bfd_vma adjust = s_start - p_end;
46745796c8dcSSimon Schubert
4675c50c785cSJohn Marino if (adjust != 0
4676c50c785cSJohn Marino && (s_start < p_end
4677c50c785cSJohn Marino || p_end < p_start))
46785796c8dcSSimon Schubert {
46795796c8dcSSimon Schubert (*_bfd_error_handler)
4680c50c785cSJohn Marino (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
4681c50c785cSJohn Marino (unsigned long) s_start, (unsigned long) p_end);
46825796c8dcSSimon Schubert adjust = 0;
4683c50c785cSJohn Marino sec->lma = p_end;
46845796c8dcSSimon Schubert }
46855796c8dcSSimon Schubert p->p_memsz += adjust;
46865796c8dcSSimon Schubert
46875796c8dcSSimon Schubert if (this_hdr->sh_type != SHT_NOBITS)
46885796c8dcSSimon Schubert {
4689cf7f2e2dSJohn Marino if (p->p_filesz + adjust < p->p_memsz)
4690cf7f2e2dSJohn Marino {
4691cf7f2e2dSJohn Marino /* We have a PROGBITS section following NOBITS ones.
4692cf7f2e2dSJohn Marino Allocate file space for the NOBITS section(s) and
4693cf7f2e2dSJohn Marino zero it. */
4694cf7f2e2dSJohn Marino adjust = p->p_memsz - p->p_filesz;
4695cf7f2e2dSJohn Marino if (!write_zeros (abfd, off, adjust))
4696cf7f2e2dSJohn Marino return FALSE;
4697cf7f2e2dSJohn Marino }
46985796c8dcSSimon Schubert off += adjust;
46995796c8dcSSimon Schubert p->p_filesz += adjust;
47005796c8dcSSimon Schubert }
47015796c8dcSSimon Schubert }
47025796c8dcSSimon Schubert
47035796c8dcSSimon Schubert if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
47045796c8dcSSimon Schubert {
47055796c8dcSSimon Schubert /* The section at i == 0 is the one that actually contains
47065796c8dcSSimon Schubert everything. */
47075796c8dcSSimon Schubert if (i == 0)
47085796c8dcSSimon Schubert {
47095796c8dcSSimon Schubert this_hdr->sh_offset = sec->filepos = off;
47105796c8dcSSimon Schubert off += this_hdr->sh_size;
47115796c8dcSSimon Schubert p->p_filesz = this_hdr->sh_size;
47125796c8dcSSimon Schubert p->p_memsz = 0;
47135796c8dcSSimon Schubert p->p_align = 1;
47145796c8dcSSimon Schubert }
47155796c8dcSSimon Schubert else
47165796c8dcSSimon Schubert {
47175796c8dcSSimon Schubert /* The rest are fake sections that shouldn't be written. */
47185796c8dcSSimon Schubert sec->filepos = 0;
47195796c8dcSSimon Schubert sec->size = 0;
47205796c8dcSSimon Schubert sec->flags = 0;
47215796c8dcSSimon Schubert continue;
47225796c8dcSSimon Schubert }
47235796c8dcSSimon Schubert }
47245796c8dcSSimon Schubert else
47255796c8dcSSimon Schubert {
47265796c8dcSSimon Schubert if (p->p_type == PT_LOAD)
47275796c8dcSSimon Schubert {
47285796c8dcSSimon Schubert this_hdr->sh_offset = sec->filepos = off;
47295796c8dcSSimon Schubert if (this_hdr->sh_type != SHT_NOBITS)
47305796c8dcSSimon Schubert off += this_hdr->sh_size;
47315796c8dcSSimon Schubert }
4732a45ae5f8SJohn Marino else if (this_hdr->sh_type == SHT_NOBITS
4733a45ae5f8SJohn Marino && (this_hdr->sh_flags & SHF_TLS) != 0
4734a45ae5f8SJohn Marino && this_hdr->sh_offset == 0)
4735a45ae5f8SJohn Marino {
4736a45ae5f8SJohn Marino /* This is a .tbss section that didn't get a PT_LOAD.
4737a45ae5f8SJohn Marino (See _bfd_elf_map_sections_to_segments "Create a
4738a45ae5f8SJohn Marino final PT_LOAD".) Set sh_offset to the value it
4739a45ae5f8SJohn Marino would have if we had created a zero p_filesz and
4740a45ae5f8SJohn Marino p_memsz PT_LOAD header for the section. This
4741a45ae5f8SJohn Marino also makes the PT_TLS header have the same
4742a45ae5f8SJohn Marino p_offset value. */
4743a45ae5f8SJohn Marino bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
4744a45ae5f8SJohn Marino off, align);
4745a45ae5f8SJohn Marino this_hdr->sh_offset = sec->filepos = off + adjust;
4746a45ae5f8SJohn Marino }
47475796c8dcSSimon Schubert
47485796c8dcSSimon Schubert if (this_hdr->sh_type != SHT_NOBITS)
47495796c8dcSSimon Schubert {
47505796c8dcSSimon Schubert p->p_filesz += this_hdr->sh_size;
47515796c8dcSSimon Schubert /* A load section without SHF_ALLOC is something like
47525796c8dcSSimon Schubert a note section in a PT_NOTE segment. These take
47535796c8dcSSimon Schubert file space but are not loaded into memory. */
47545796c8dcSSimon Schubert if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
47555796c8dcSSimon Schubert p->p_memsz += this_hdr->sh_size;
47565796c8dcSSimon Schubert }
47575796c8dcSSimon Schubert else if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
47585796c8dcSSimon Schubert {
47595796c8dcSSimon Schubert if (p->p_type == PT_TLS)
47605796c8dcSSimon Schubert p->p_memsz += this_hdr->sh_size;
47615796c8dcSSimon Schubert
47625796c8dcSSimon Schubert /* .tbss is special. It doesn't contribute to p_memsz of
47635796c8dcSSimon Schubert normal segments. */
47645796c8dcSSimon Schubert else if ((this_hdr->sh_flags & SHF_TLS) == 0)
47655796c8dcSSimon Schubert p->p_memsz += this_hdr->sh_size;
47665796c8dcSSimon Schubert }
47675796c8dcSSimon Schubert
47685796c8dcSSimon Schubert if (align > p->p_align
47695796c8dcSSimon Schubert && !m->p_align_valid
47705796c8dcSSimon Schubert && (p->p_type != PT_LOAD
47715796c8dcSSimon Schubert || (abfd->flags & D_PAGED) == 0))
47725796c8dcSSimon Schubert p->p_align = align;
47735796c8dcSSimon Schubert }
47745796c8dcSSimon Schubert
47755796c8dcSSimon Schubert if (!m->p_flags_valid)
47765796c8dcSSimon Schubert {
47775796c8dcSSimon Schubert p->p_flags |= PF_R;
47785796c8dcSSimon Schubert if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
47795796c8dcSSimon Schubert p->p_flags |= PF_X;
47805796c8dcSSimon Schubert if ((this_hdr->sh_flags & SHF_WRITE) != 0)
47815796c8dcSSimon Schubert p->p_flags |= PF_W;
47825796c8dcSSimon Schubert }
47835796c8dcSSimon Schubert }
47845796c8dcSSimon Schubert off -= off_adjust;
47855796c8dcSSimon Schubert
47865796c8dcSSimon Schubert /* Check that all sections are in a PT_LOAD segment.
47875796c8dcSSimon Schubert Don't check funky gdb generated core files. */
47885796c8dcSSimon Schubert if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core)
4789cf7f2e2dSJohn Marino {
4790cf7f2e2dSJohn Marino bfd_boolean check_vma = TRUE;
4791cf7f2e2dSJohn Marino
4792cf7f2e2dSJohn Marino for (i = 1; i < m->count; i++)
4793cf7f2e2dSJohn Marino if (m->sections[i]->vma == m->sections[i - 1]->vma
4794cf7f2e2dSJohn Marino && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i])
4795cf7f2e2dSJohn Marino ->this_hdr), p) != 0
4796cf7f2e2dSJohn Marino && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1])
4797cf7f2e2dSJohn Marino ->this_hdr), p) != 0)
4798cf7f2e2dSJohn Marino {
4799cf7f2e2dSJohn Marino /* Looks like we have overlays packed into the segment. */
4800cf7f2e2dSJohn Marino check_vma = FALSE;
4801cf7f2e2dSJohn Marino break;
4802cf7f2e2dSJohn Marino }
4803cf7f2e2dSJohn Marino
4804cf7f2e2dSJohn Marino for (i = 0; i < m->count; i++)
48055796c8dcSSimon Schubert {
48065796c8dcSSimon Schubert Elf_Internal_Shdr *this_hdr;
48075796c8dcSSimon Schubert asection *sec;
48085796c8dcSSimon Schubert
4809cf7f2e2dSJohn Marino sec = m->sections[i];
48105796c8dcSSimon Schubert this_hdr = &(elf_section_data(sec)->this_hdr);
4811a45ae5f8SJohn Marino if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
4812a45ae5f8SJohn Marino && !ELF_TBSS_SPECIAL (this_hdr, p))
48135796c8dcSSimon Schubert {
48145796c8dcSSimon Schubert (*_bfd_error_handler)
48155796c8dcSSimon Schubert (_("%B: section `%A' can't be allocated in segment %d"),
48165796c8dcSSimon Schubert abfd, sec, j);
48175796c8dcSSimon Schubert print_segment_map (m);
4818cf7f2e2dSJohn Marino }
48195796c8dcSSimon Schubert }
48205796c8dcSSimon Schubert }
48215796c8dcSSimon Schubert }
48225796c8dcSSimon Schubert
4823*ef5ccd6cSJohn Marino elf_next_file_pos (abfd) = off;
48245796c8dcSSimon Schubert return TRUE;
48255796c8dcSSimon Schubert }
48265796c8dcSSimon Schubert
48275796c8dcSSimon Schubert /* Assign file positions for the other sections. */
48285796c8dcSSimon Schubert
48295796c8dcSSimon Schubert static bfd_boolean
assign_file_positions_for_non_load_sections(bfd * abfd,struct bfd_link_info * link_info)48305796c8dcSSimon Schubert assign_file_positions_for_non_load_sections (bfd *abfd,
48315796c8dcSSimon Schubert struct bfd_link_info *link_info)
48325796c8dcSSimon Schubert {
48335796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
48345796c8dcSSimon Schubert Elf_Internal_Shdr **i_shdrpp;
48355796c8dcSSimon Schubert Elf_Internal_Shdr **hdrpp;
48365796c8dcSSimon Schubert Elf_Internal_Phdr *phdrs;
48375796c8dcSSimon Schubert Elf_Internal_Phdr *p;
48385796c8dcSSimon Schubert struct elf_segment_map *m;
4839*ef5ccd6cSJohn Marino struct elf_segment_map *hdrs_segment;
48405796c8dcSSimon Schubert bfd_vma filehdr_vaddr, filehdr_paddr;
48415796c8dcSSimon Schubert bfd_vma phdrs_vaddr, phdrs_paddr;
48425796c8dcSSimon Schubert file_ptr off;
48435796c8dcSSimon Schubert unsigned int num_sec;
48445796c8dcSSimon Schubert unsigned int i;
48455796c8dcSSimon Schubert unsigned int count;
48465796c8dcSSimon Schubert
48475796c8dcSSimon Schubert i_shdrpp = elf_elfsections (abfd);
48485796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
4849*ef5ccd6cSJohn Marino off = elf_next_file_pos (abfd);
48505796c8dcSSimon Schubert for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
48515796c8dcSSimon Schubert {
48525796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
48535796c8dcSSimon Schubert
48545796c8dcSSimon Schubert hdr = *hdrpp;
48555796c8dcSSimon Schubert if (hdr->bfd_section != NULL
48565796c8dcSSimon Schubert && (hdr->bfd_section->filepos != 0
48575796c8dcSSimon Schubert || (hdr->sh_type == SHT_NOBITS
48585796c8dcSSimon Schubert && hdr->contents == NULL)))
48595796c8dcSSimon Schubert BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
48605796c8dcSSimon Schubert else if ((hdr->sh_flags & SHF_ALLOC) != 0)
48615796c8dcSSimon Schubert {
4862*ef5ccd6cSJohn Marino if (hdr->sh_size != 0)
4863c50c785cSJohn Marino (*_bfd_error_handler)
48645796c8dcSSimon Schubert (_("%B: warning: allocated section `%s' not in segment"),
48655796c8dcSSimon Schubert abfd,
48665796c8dcSSimon Schubert (hdr->bfd_section == NULL
48675796c8dcSSimon Schubert ? "*unknown*"
4868c50c785cSJohn Marino : hdr->bfd_section->name));
48695796c8dcSSimon Schubert /* We don't need to page align empty sections. */
48705796c8dcSSimon Schubert if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
48715796c8dcSSimon Schubert off += vma_page_aligned_bias (hdr->sh_addr, off,
48725796c8dcSSimon Schubert bed->maxpagesize);
48735796c8dcSSimon Schubert else
48745796c8dcSSimon Schubert off += vma_page_aligned_bias (hdr->sh_addr, off,
48755796c8dcSSimon Schubert hdr->sh_addralign);
48765796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (hdr, off,
48775796c8dcSSimon Schubert FALSE);
48785796c8dcSSimon Schubert }
48795796c8dcSSimon Schubert else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
48805796c8dcSSimon Schubert && hdr->bfd_section == NULL)
4881*ef5ccd6cSJohn Marino || hdr == i_shdrpp[elf_onesymtab (abfd)]
4882*ef5ccd6cSJohn Marino || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
4883*ef5ccd6cSJohn Marino || hdr == i_shdrpp[elf_strtab_sec (abfd)])
48845796c8dcSSimon Schubert hdr->sh_offset = -1;
48855796c8dcSSimon Schubert else
48865796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
48875796c8dcSSimon Schubert }
48885796c8dcSSimon Schubert
48895796c8dcSSimon Schubert /* Now that we have set the section file positions, we can set up
48905796c8dcSSimon Schubert the file positions for the non PT_LOAD segments. */
48915796c8dcSSimon Schubert count = 0;
48925796c8dcSSimon Schubert filehdr_vaddr = 0;
48935796c8dcSSimon Schubert filehdr_paddr = 0;
48945796c8dcSSimon Schubert phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
48955796c8dcSSimon Schubert phdrs_paddr = 0;
4896*ef5ccd6cSJohn Marino hdrs_segment = NULL;
48975796c8dcSSimon Schubert phdrs = elf_tdata (abfd)->phdr;
4898*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
48995796c8dcSSimon Schubert {
49005796c8dcSSimon Schubert ++count;
49015796c8dcSSimon Schubert if (p->p_type != PT_LOAD)
49025796c8dcSSimon Schubert continue;
49035796c8dcSSimon Schubert
49045796c8dcSSimon Schubert if (m->includes_filehdr)
49055796c8dcSSimon Schubert {
49065796c8dcSSimon Schubert filehdr_vaddr = p->p_vaddr;
49075796c8dcSSimon Schubert filehdr_paddr = p->p_paddr;
49085796c8dcSSimon Schubert }
49095796c8dcSSimon Schubert if (m->includes_phdrs)
49105796c8dcSSimon Schubert {
49115796c8dcSSimon Schubert phdrs_vaddr = p->p_vaddr;
49125796c8dcSSimon Schubert phdrs_paddr = p->p_paddr;
49135796c8dcSSimon Schubert if (m->includes_filehdr)
49145796c8dcSSimon Schubert {
4915*ef5ccd6cSJohn Marino hdrs_segment = m;
49165796c8dcSSimon Schubert phdrs_vaddr += bed->s->sizeof_ehdr;
49175796c8dcSSimon Schubert phdrs_paddr += bed->s->sizeof_ehdr;
49185796c8dcSSimon Schubert }
49195796c8dcSSimon Schubert }
49205796c8dcSSimon Schubert }
49215796c8dcSSimon Schubert
4922*ef5ccd6cSJohn Marino if (hdrs_segment != NULL && link_info != NULL)
4923*ef5ccd6cSJohn Marino {
4924*ef5ccd6cSJohn Marino /* There is a segment that contains both the file headers and the
4925*ef5ccd6cSJohn Marino program headers, so provide a symbol __ehdr_start pointing there.
4926*ef5ccd6cSJohn Marino A program can use this to examine itself robustly. */
4927*ef5ccd6cSJohn Marino
4928*ef5ccd6cSJohn Marino struct elf_link_hash_entry *hash
4929*ef5ccd6cSJohn Marino = elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
4930*ef5ccd6cSJohn Marino FALSE, FALSE, TRUE);
4931*ef5ccd6cSJohn Marino /* If the symbol was referenced and not defined, define it. */
4932*ef5ccd6cSJohn Marino if (hash != NULL
4933*ef5ccd6cSJohn Marino && (hash->root.type == bfd_link_hash_new
4934*ef5ccd6cSJohn Marino || hash->root.type == bfd_link_hash_undefined
4935*ef5ccd6cSJohn Marino || hash->root.type == bfd_link_hash_undefweak
4936*ef5ccd6cSJohn Marino || hash->root.type == bfd_link_hash_common))
4937*ef5ccd6cSJohn Marino {
4938*ef5ccd6cSJohn Marino asection *s = NULL;
4939*ef5ccd6cSJohn Marino if (hdrs_segment->count != 0)
4940*ef5ccd6cSJohn Marino /* The segment contains sections, so use the first one. */
4941*ef5ccd6cSJohn Marino s = hdrs_segment->sections[0];
4942*ef5ccd6cSJohn Marino else
4943*ef5ccd6cSJohn Marino /* Use the first (i.e. lowest-addressed) section in any segment. */
4944*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd); m != NULL; m = m->next)
4945*ef5ccd6cSJohn Marino if (m->count != 0)
4946*ef5ccd6cSJohn Marino {
4947*ef5ccd6cSJohn Marino s = m->sections[0];
4948*ef5ccd6cSJohn Marino break;
4949*ef5ccd6cSJohn Marino }
4950*ef5ccd6cSJohn Marino
4951*ef5ccd6cSJohn Marino if (s != NULL)
4952*ef5ccd6cSJohn Marino {
4953*ef5ccd6cSJohn Marino hash->root.u.def.value = filehdr_vaddr - s->vma;
4954*ef5ccd6cSJohn Marino hash->root.u.def.section = s;
4955*ef5ccd6cSJohn Marino }
4956*ef5ccd6cSJohn Marino else
4957*ef5ccd6cSJohn Marino {
4958*ef5ccd6cSJohn Marino hash->root.u.def.value = filehdr_vaddr;
4959*ef5ccd6cSJohn Marino hash->root.u.def.section = bfd_abs_section_ptr;
4960*ef5ccd6cSJohn Marino }
4961*ef5ccd6cSJohn Marino
4962*ef5ccd6cSJohn Marino hash->root.type = bfd_link_hash_defined;
4963*ef5ccd6cSJohn Marino hash->def_regular = 1;
4964*ef5ccd6cSJohn Marino hash->non_elf = 0;
4965*ef5ccd6cSJohn Marino }
4966*ef5ccd6cSJohn Marino }
4967*ef5ccd6cSJohn Marino
4968*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
49695796c8dcSSimon Schubert {
49705796c8dcSSimon Schubert if (p->p_type == PT_GNU_RELRO)
49715796c8dcSSimon Schubert {
49725796c8dcSSimon Schubert const Elf_Internal_Phdr *lp;
4973*ef5ccd6cSJohn Marino struct elf_segment_map *lm;
49745796c8dcSSimon Schubert
49755796c8dcSSimon Schubert if (link_info != NULL)
49765796c8dcSSimon Schubert {
49775796c8dcSSimon Schubert /* During linking the range of the RELRO segment is passed
49785796c8dcSSimon Schubert in link_info. */
4979*ef5ccd6cSJohn Marino for (lm = elf_seg_map (abfd), lp = phdrs;
4980*ef5ccd6cSJohn Marino lm != NULL;
4981*ef5ccd6cSJohn Marino lm = lm->next, lp++)
49825796c8dcSSimon Schubert {
49835796c8dcSSimon Schubert if (lp->p_type == PT_LOAD
49845796c8dcSSimon Schubert && lp->p_vaddr < link_info->relro_end
4985*ef5ccd6cSJohn Marino && lp->p_vaddr + lp->p_filesz >= link_info->relro_end
4986*ef5ccd6cSJohn Marino && lm->count != 0
4987*ef5ccd6cSJohn Marino && lm->sections[0]->vma >= link_info->relro_start)
49885796c8dcSSimon Schubert break;
49895796c8dcSSimon Schubert }
4990*ef5ccd6cSJohn Marino
4991*ef5ccd6cSJohn Marino /* PR ld/14207. If the RELRO segment doesn't fit in the
4992*ef5ccd6cSJohn Marino LOAD segment, it should be removed. */
4993*ef5ccd6cSJohn Marino BFD_ASSERT (lm != NULL);
49945796c8dcSSimon Schubert }
49955796c8dcSSimon Schubert else
49965796c8dcSSimon Schubert {
49975796c8dcSSimon Schubert /* Otherwise we are copying an executable or shared
49985796c8dcSSimon Schubert library, but we need to use the same linker logic. */
49995796c8dcSSimon Schubert for (lp = phdrs; lp < phdrs + count; ++lp)
50005796c8dcSSimon Schubert {
50015796c8dcSSimon Schubert if (lp->p_type == PT_LOAD
50025796c8dcSSimon Schubert && lp->p_paddr == p->p_paddr)
50035796c8dcSSimon Schubert break;
50045796c8dcSSimon Schubert }
50055796c8dcSSimon Schubert }
50065796c8dcSSimon Schubert
50075796c8dcSSimon Schubert if (lp < phdrs + count)
50085796c8dcSSimon Schubert {
50095796c8dcSSimon Schubert p->p_vaddr = lp->p_vaddr;
50105796c8dcSSimon Schubert p->p_paddr = lp->p_paddr;
50115796c8dcSSimon Schubert p->p_offset = lp->p_offset;
50125796c8dcSSimon Schubert if (link_info != NULL)
50135796c8dcSSimon Schubert p->p_filesz = link_info->relro_end - lp->p_vaddr;
50145796c8dcSSimon Schubert else if (m->p_size_valid)
50155796c8dcSSimon Schubert p->p_filesz = m->p_size;
50165796c8dcSSimon Schubert else
50175796c8dcSSimon Schubert abort ();
50185796c8dcSSimon Schubert p->p_memsz = p->p_filesz;
5019*ef5ccd6cSJohn Marino /* Preserve the alignment and flags if they are valid. The
5020*ef5ccd6cSJohn Marino gold linker generates RW/4 for the PT_GNU_RELRO section.
5021*ef5ccd6cSJohn Marino It is better for objcopy/strip to honor these attributes
5022*ef5ccd6cSJohn Marino otherwise gdb will choke when using separate debug files.
5023*ef5ccd6cSJohn Marino */
5024*ef5ccd6cSJohn Marino if (!m->p_align_valid)
50255796c8dcSSimon Schubert p->p_align = 1;
5026*ef5ccd6cSJohn Marino if (!m->p_flags_valid)
50275796c8dcSSimon Schubert p->p_flags = (lp->p_flags & ~PF_W);
50285796c8dcSSimon Schubert }
50295796c8dcSSimon Schubert else
50305796c8dcSSimon Schubert {
50315796c8dcSSimon Schubert memset (p, 0, sizeof *p);
50325796c8dcSSimon Schubert p->p_type = PT_NULL;
50335796c8dcSSimon Schubert }
50345796c8dcSSimon Schubert }
5035*ef5ccd6cSJohn Marino else if (p->p_type == PT_GNU_STACK)
5036*ef5ccd6cSJohn Marino {
5037*ef5ccd6cSJohn Marino if (m->p_size_valid)
5038*ef5ccd6cSJohn Marino p->p_memsz = m->p_size;
5039*ef5ccd6cSJohn Marino }
50405796c8dcSSimon Schubert else if (m->count != 0)
50415796c8dcSSimon Schubert {
50425796c8dcSSimon Schubert if (p->p_type != PT_LOAD
50435796c8dcSSimon Schubert && (p->p_type != PT_NOTE
50445796c8dcSSimon Schubert || bfd_get_format (abfd) != bfd_core))
50455796c8dcSSimon Schubert {
50465796c8dcSSimon Schubert BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
50475796c8dcSSimon Schubert
5048a45ae5f8SJohn Marino p->p_filesz = 0;
50495796c8dcSSimon Schubert p->p_offset = m->sections[0]->filepos;
5050a45ae5f8SJohn Marino for (i = m->count; i-- != 0;)
5051a45ae5f8SJohn Marino {
5052a45ae5f8SJohn Marino asection *sect = m->sections[i];
5053a45ae5f8SJohn Marino Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
5054a45ae5f8SJohn Marino if (hdr->sh_type != SHT_NOBITS)
5055a45ae5f8SJohn Marino {
5056a45ae5f8SJohn Marino p->p_filesz = (sect->filepos - m->sections[0]->filepos
5057a45ae5f8SJohn Marino + hdr->sh_size);
5058a45ae5f8SJohn Marino break;
5059a45ae5f8SJohn Marino }
5060a45ae5f8SJohn Marino }
50615796c8dcSSimon Schubert }
50625796c8dcSSimon Schubert }
50635796c8dcSSimon Schubert else if (m->includes_filehdr)
50645796c8dcSSimon Schubert {
50655796c8dcSSimon Schubert p->p_vaddr = filehdr_vaddr;
50665796c8dcSSimon Schubert if (! m->p_paddr_valid)
50675796c8dcSSimon Schubert p->p_paddr = filehdr_paddr;
50685796c8dcSSimon Schubert }
50695796c8dcSSimon Schubert else if (m->includes_phdrs)
50705796c8dcSSimon Schubert {
50715796c8dcSSimon Schubert p->p_vaddr = phdrs_vaddr;
50725796c8dcSSimon Schubert if (! m->p_paddr_valid)
50735796c8dcSSimon Schubert p->p_paddr = phdrs_paddr;
50745796c8dcSSimon Schubert }
50755796c8dcSSimon Schubert }
50765796c8dcSSimon Schubert
5077*ef5ccd6cSJohn Marino elf_next_file_pos (abfd) = off;
50785796c8dcSSimon Schubert
50795796c8dcSSimon Schubert return TRUE;
50805796c8dcSSimon Schubert }
50815796c8dcSSimon Schubert
50825796c8dcSSimon Schubert /* Work out the file positions of all the sections. This is called by
50835796c8dcSSimon Schubert _bfd_elf_compute_section_file_positions. All the section sizes and
50845796c8dcSSimon Schubert VMAs must be known before this is called.
50855796c8dcSSimon Schubert
50865796c8dcSSimon Schubert Reloc sections come in two flavours: Those processed specially as
50875796c8dcSSimon Schubert "side-channel" data attached to a section to which they apply, and
50885796c8dcSSimon Schubert those that bfd doesn't process as relocations. The latter sort are
50895796c8dcSSimon Schubert stored in a normal bfd section by bfd_section_from_shdr. We don't
50905796c8dcSSimon Schubert consider the former sort here, unless they form part of the loadable
50915796c8dcSSimon Schubert image. Reloc sections not assigned here will be handled later by
50925796c8dcSSimon Schubert assign_file_positions_for_relocs.
50935796c8dcSSimon Schubert
50945796c8dcSSimon Schubert We also don't set the positions of the .symtab and .strtab here. */
50955796c8dcSSimon Schubert
50965796c8dcSSimon Schubert static bfd_boolean
assign_file_positions_except_relocs(bfd * abfd,struct bfd_link_info * link_info)50975796c8dcSSimon Schubert assign_file_positions_except_relocs (bfd *abfd,
50985796c8dcSSimon Schubert struct bfd_link_info *link_info)
50995796c8dcSSimon Schubert {
51005796c8dcSSimon Schubert struct elf_obj_tdata *tdata = elf_tdata (abfd);
51015796c8dcSSimon Schubert Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
51025796c8dcSSimon Schubert file_ptr off;
51035796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
51045796c8dcSSimon Schubert
51055796c8dcSSimon Schubert if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
51065796c8dcSSimon Schubert && bfd_get_format (abfd) != bfd_core)
51075796c8dcSSimon Schubert {
51085796c8dcSSimon Schubert Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
51095796c8dcSSimon Schubert unsigned int num_sec = elf_numsections (abfd);
51105796c8dcSSimon Schubert Elf_Internal_Shdr **hdrpp;
51115796c8dcSSimon Schubert unsigned int i;
51125796c8dcSSimon Schubert
51135796c8dcSSimon Schubert /* Start after the ELF header. */
51145796c8dcSSimon Schubert off = i_ehdrp->e_ehsize;
51155796c8dcSSimon Schubert
51165796c8dcSSimon Schubert /* We are not creating an executable, which means that we are
51175796c8dcSSimon Schubert not creating a program header, and that the actual order of
51185796c8dcSSimon Schubert the sections in the file is unimportant. */
51195796c8dcSSimon Schubert for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
51205796c8dcSSimon Schubert {
51215796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
51225796c8dcSSimon Schubert
51235796c8dcSSimon Schubert hdr = *hdrpp;
51245796c8dcSSimon Schubert if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
51255796c8dcSSimon Schubert && hdr->bfd_section == NULL)
5126*ef5ccd6cSJohn Marino || i == elf_onesymtab (abfd)
5127*ef5ccd6cSJohn Marino || i == elf_symtab_shndx (abfd)
5128*ef5ccd6cSJohn Marino || i == elf_strtab_sec (abfd))
51295796c8dcSSimon Schubert {
51305796c8dcSSimon Schubert hdr->sh_offset = -1;
51315796c8dcSSimon Schubert }
51325796c8dcSSimon Schubert else
51335796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
51345796c8dcSSimon Schubert }
51355796c8dcSSimon Schubert }
51365796c8dcSSimon Schubert else
51375796c8dcSSimon Schubert {
51385796c8dcSSimon Schubert unsigned int alloc;
51395796c8dcSSimon Schubert
51405796c8dcSSimon Schubert /* Assign file positions for the loaded sections based on the
51415796c8dcSSimon Schubert assignment of sections to segments. */
51425796c8dcSSimon Schubert if (!assign_file_positions_for_load_sections (abfd, link_info))
51435796c8dcSSimon Schubert return FALSE;
51445796c8dcSSimon Schubert
51455796c8dcSSimon Schubert /* And for non-load sections. */
51465796c8dcSSimon Schubert if (!assign_file_positions_for_non_load_sections (abfd, link_info))
51475796c8dcSSimon Schubert return FALSE;
51485796c8dcSSimon Schubert
51495796c8dcSSimon Schubert if (bed->elf_backend_modify_program_headers != NULL)
51505796c8dcSSimon Schubert {
51515796c8dcSSimon Schubert if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
51525796c8dcSSimon Schubert return FALSE;
51535796c8dcSSimon Schubert }
51545796c8dcSSimon Schubert
51555796c8dcSSimon Schubert /* Write out the program headers. */
5156*ef5ccd6cSJohn Marino alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
51575796c8dcSSimon Schubert if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
51585796c8dcSSimon Schubert || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
51595796c8dcSSimon Schubert return FALSE;
51605796c8dcSSimon Schubert
5161*ef5ccd6cSJohn Marino off = elf_next_file_pos (abfd);
51625796c8dcSSimon Schubert }
51635796c8dcSSimon Schubert
51645796c8dcSSimon Schubert /* Place the section headers. */
51655796c8dcSSimon Schubert off = align_file_position (off, 1 << bed->s->log_file_align);
51665796c8dcSSimon Schubert i_ehdrp->e_shoff = off;
51675796c8dcSSimon Schubert off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
51685796c8dcSSimon Schubert
5169*ef5ccd6cSJohn Marino elf_next_file_pos (abfd) = off;
51705796c8dcSSimon Schubert
51715796c8dcSSimon Schubert return TRUE;
51725796c8dcSSimon Schubert }
51735796c8dcSSimon Schubert
51745796c8dcSSimon Schubert static bfd_boolean
prep_headers(bfd * abfd)51755796c8dcSSimon Schubert prep_headers (bfd *abfd)
51765796c8dcSSimon Schubert {
5177cf7f2e2dSJohn Marino Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form. */
51785796c8dcSSimon Schubert struct elf_strtab_hash *shstrtab;
51795796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
51805796c8dcSSimon Schubert
51815796c8dcSSimon Schubert i_ehdrp = elf_elfheader (abfd);
51825796c8dcSSimon Schubert
51835796c8dcSSimon Schubert shstrtab = _bfd_elf_strtab_init ();
51845796c8dcSSimon Schubert if (shstrtab == NULL)
51855796c8dcSSimon Schubert return FALSE;
51865796c8dcSSimon Schubert
51875796c8dcSSimon Schubert elf_shstrtab (abfd) = shstrtab;
51885796c8dcSSimon Schubert
51895796c8dcSSimon Schubert i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
51905796c8dcSSimon Schubert i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
51915796c8dcSSimon Schubert i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
51925796c8dcSSimon Schubert i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;
51935796c8dcSSimon Schubert
51945796c8dcSSimon Schubert i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
51955796c8dcSSimon Schubert i_ehdrp->e_ident[EI_DATA] =
51965796c8dcSSimon Schubert bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
51975796c8dcSSimon Schubert i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
51985796c8dcSSimon Schubert
51995796c8dcSSimon Schubert if ((abfd->flags & DYNAMIC) != 0)
52005796c8dcSSimon Schubert i_ehdrp->e_type = ET_DYN;
52015796c8dcSSimon Schubert else if ((abfd->flags & EXEC_P) != 0)
52025796c8dcSSimon Schubert i_ehdrp->e_type = ET_EXEC;
52035796c8dcSSimon Schubert else if (bfd_get_format (abfd) == bfd_core)
52045796c8dcSSimon Schubert i_ehdrp->e_type = ET_CORE;
52055796c8dcSSimon Schubert else
52065796c8dcSSimon Schubert i_ehdrp->e_type = ET_REL;
52075796c8dcSSimon Schubert
52085796c8dcSSimon Schubert switch (bfd_get_arch (abfd))
52095796c8dcSSimon Schubert {
52105796c8dcSSimon Schubert case bfd_arch_unknown:
52115796c8dcSSimon Schubert i_ehdrp->e_machine = EM_NONE;
52125796c8dcSSimon Schubert break;
52135796c8dcSSimon Schubert
52145796c8dcSSimon Schubert /* There used to be a long list of cases here, each one setting
52155796c8dcSSimon Schubert e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
52165796c8dcSSimon Schubert in the corresponding bfd definition. To avoid duplication,
52175796c8dcSSimon Schubert the switch was removed. Machines that need special handling
52185796c8dcSSimon Schubert can generally do it in elf_backend_final_write_processing(),
52195796c8dcSSimon Schubert unless they need the information earlier than the final write.
52205796c8dcSSimon Schubert Such need can generally be supplied by replacing the tests for
52215796c8dcSSimon Schubert e_machine with the conditions used to determine it. */
52225796c8dcSSimon Schubert default:
52235796c8dcSSimon Schubert i_ehdrp->e_machine = bed->elf_machine_code;
52245796c8dcSSimon Schubert }
52255796c8dcSSimon Schubert
52265796c8dcSSimon Schubert i_ehdrp->e_version = bed->s->ev_current;
52275796c8dcSSimon Schubert i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
52285796c8dcSSimon Schubert
52295796c8dcSSimon Schubert /* No program header, for now. */
52305796c8dcSSimon Schubert i_ehdrp->e_phoff = 0;
52315796c8dcSSimon Schubert i_ehdrp->e_phentsize = 0;
52325796c8dcSSimon Schubert i_ehdrp->e_phnum = 0;
52335796c8dcSSimon Schubert
52345796c8dcSSimon Schubert /* Each bfd section is section header entry. */
52355796c8dcSSimon Schubert i_ehdrp->e_entry = bfd_get_start_address (abfd);
52365796c8dcSSimon Schubert i_ehdrp->e_shentsize = bed->s->sizeof_shdr;
52375796c8dcSSimon Schubert
52385796c8dcSSimon Schubert /* If we're building an executable, we'll need a program header table. */
52395796c8dcSSimon Schubert if (abfd->flags & EXEC_P)
52405796c8dcSSimon Schubert /* It all happens later. */
52415796c8dcSSimon Schubert ;
52425796c8dcSSimon Schubert else
52435796c8dcSSimon Schubert {
52445796c8dcSSimon Schubert i_ehdrp->e_phentsize = 0;
52455796c8dcSSimon Schubert i_ehdrp->e_phoff = 0;
52465796c8dcSSimon Schubert }
52475796c8dcSSimon Schubert
52485796c8dcSSimon Schubert elf_tdata (abfd)->symtab_hdr.sh_name =
52495796c8dcSSimon Schubert (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE);
52505796c8dcSSimon Schubert elf_tdata (abfd)->strtab_hdr.sh_name =
52515796c8dcSSimon Schubert (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE);
52525796c8dcSSimon Schubert elf_tdata (abfd)->shstrtab_hdr.sh_name =
52535796c8dcSSimon Schubert (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
52545796c8dcSSimon Schubert if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
52555796c8dcSSimon Schubert || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
52565796c8dcSSimon Schubert || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
52575796c8dcSSimon Schubert return FALSE;
52585796c8dcSSimon Schubert
52595796c8dcSSimon Schubert return TRUE;
52605796c8dcSSimon Schubert }
52615796c8dcSSimon Schubert
52625796c8dcSSimon Schubert /* Assign file positions for all the reloc sections which are not part
52635796c8dcSSimon Schubert of the loadable file image. */
52645796c8dcSSimon Schubert
52655796c8dcSSimon Schubert void
_bfd_elf_assign_file_positions_for_relocs(bfd * abfd)52665796c8dcSSimon Schubert _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
52675796c8dcSSimon Schubert {
52685796c8dcSSimon Schubert file_ptr off;
52695796c8dcSSimon Schubert unsigned int i, num_sec;
52705796c8dcSSimon Schubert Elf_Internal_Shdr **shdrpp;
52715796c8dcSSimon Schubert
5272*ef5ccd6cSJohn Marino off = elf_next_file_pos (abfd);
52735796c8dcSSimon Schubert
52745796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
52755796c8dcSSimon Schubert for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
52765796c8dcSSimon Schubert {
52775796c8dcSSimon Schubert Elf_Internal_Shdr *shdrp;
52785796c8dcSSimon Schubert
52795796c8dcSSimon Schubert shdrp = *shdrpp;
52805796c8dcSSimon Schubert if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
52815796c8dcSSimon Schubert && shdrp->sh_offset == -1)
52825796c8dcSSimon Schubert off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
52835796c8dcSSimon Schubert }
52845796c8dcSSimon Schubert
5285*ef5ccd6cSJohn Marino elf_next_file_pos (abfd) = off;
52865796c8dcSSimon Schubert }
52875796c8dcSSimon Schubert
52885796c8dcSSimon Schubert bfd_boolean
_bfd_elf_write_object_contents(bfd * abfd)52895796c8dcSSimon Schubert _bfd_elf_write_object_contents (bfd *abfd)
52905796c8dcSSimon Schubert {
52915796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
52925796c8dcSSimon Schubert Elf_Internal_Shdr **i_shdrp;
52935796c8dcSSimon Schubert bfd_boolean failed;
52945796c8dcSSimon Schubert unsigned int count, num_sec;
5295*ef5ccd6cSJohn Marino struct elf_obj_tdata *t;
52965796c8dcSSimon Schubert
52975796c8dcSSimon Schubert if (! abfd->output_has_begun
52985796c8dcSSimon Schubert && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
52995796c8dcSSimon Schubert return FALSE;
53005796c8dcSSimon Schubert
53015796c8dcSSimon Schubert i_shdrp = elf_elfsections (abfd);
53025796c8dcSSimon Schubert
53035796c8dcSSimon Schubert failed = FALSE;
53045796c8dcSSimon Schubert bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
53055796c8dcSSimon Schubert if (failed)
53065796c8dcSSimon Schubert return FALSE;
53075796c8dcSSimon Schubert
53085796c8dcSSimon Schubert _bfd_elf_assign_file_positions_for_relocs (abfd);
53095796c8dcSSimon Schubert
53105796c8dcSSimon Schubert /* After writing the headers, we need to write the sections too... */
53115796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
53125796c8dcSSimon Schubert for (count = 1; count < num_sec; count++)
53135796c8dcSSimon Schubert {
53145796c8dcSSimon Schubert if (bed->elf_backend_section_processing)
53155796c8dcSSimon Schubert (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
53165796c8dcSSimon Schubert if (i_shdrp[count]->contents)
53175796c8dcSSimon Schubert {
53185796c8dcSSimon Schubert bfd_size_type amt = i_shdrp[count]->sh_size;
53195796c8dcSSimon Schubert
53205796c8dcSSimon Schubert if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
53215796c8dcSSimon Schubert || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
53225796c8dcSSimon Schubert return FALSE;
53235796c8dcSSimon Schubert }
53245796c8dcSSimon Schubert }
53255796c8dcSSimon Schubert
53265796c8dcSSimon Schubert /* Write out the section header names. */
5327*ef5ccd6cSJohn Marino t = elf_tdata (abfd);
53285796c8dcSSimon Schubert if (elf_shstrtab (abfd) != NULL
5329*ef5ccd6cSJohn Marino && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0
53305796c8dcSSimon Schubert || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
53315796c8dcSSimon Schubert return FALSE;
53325796c8dcSSimon Schubert
53335796c8dcSSimon Schubert if (bed->elf_backend_final_write_processing)
5334*ef5ccd6cSJohn Marino (*bed->elf_backend_final_write_processing) (abfd, elf_linker (abfd));
53355796c8dcSSimon Schubert
53365796c8dcSSimon Schubert if (!bed->s->write_shdrs_and_ehdr (abfd))
53375796c8dcSSimon Schubert return FALSE;
53385796c8dcSSimon Schubert
53395796c8dcSSimon Schubert /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0]. */
5340*ef5ccd6cSJohn Marino if (t->o->build_id.after_write_object_contents != NULL)
5341*ef5ccd6cSJohn Marino return (*t->o->build_id.after_write_object_contents) (abfd);
53425796c8dcSSimon Schubert
53435796c8dcSSimon Schubert return TRUE;
53445796c8dcSSimon Schubert }
53455796c8dcSSimon Schubert
53465796c8dcSSimon Schubert bfd_boolean
_bfd_elf_write_corefile_contents(bfd * abfd)53475796c8dcSSimon Schubert _bfd_elf_write_corefile_contents (bfd *abfd)
53485796c8dcSSimon Schubert {
53495796c8dcSSimon Schubert /* Hopefully this can be done just like an object file. */
53505796c8dcSSimon Schubert return _bfd_elf_write_object_contents (abfd);
53515796c8dcSSimon Schubert }
53525796c8dcSSimon Schubert
53535796c8dcSSimon Schubert /* Given a section, search the header to find them. */
53545796c8dcSSimon Schubert
53555796c8dcSSimon Schubert unsigned int
_bfd_elf_section_from_bfd_section(bfd * abfd,struct bfd_section * asect)53565796c8dcSSimon Schubert _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
53575796c8dcSSimon Schubert {
53585796c8dcSSimon Schubert const struct elf_backend_data *bed;
5359cf7f2e2dSJohn Marino unsigned int sec_index;
53605796c8dcSSimon Schubert
53615796c8dcSSimon Schubert if (elf_section_data (asect) != NULL
53625796c8dcSSimon Schubert && elf_section_data (asect)->this_idx != 0)
53635796c8dcSSimon Schubert return elf_section_data (asect)->this_idx;
53645796c8dcSSimon Schubert
53655796c8dcSSimon Schubert if (bfd_is_abs_section (asect))
5366cf7f2e2dSJohn Marino sec_index = SHN_ABS;
53675796c8dcSSimon Schubert else if (bfd_is_com_section (asect))
5368cf7f2e2dSJohn Marino sec_index = SHN_COMMON;
53695796c8dcSSimon Schubert else if (bfd_is_und_section (asect))
5370cf7f2e2dSJohn Marino sec_index = SHN_UNDEF;
53715796c8dcSSimon Schubert else
5372cf7f2e2dSJohn Marino sec_index = SHN_BAD;
53735796c8dcSSimon Schubert
53745796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
53755796c8dcSSimon Schubert if (bed->elf_backend_section_from_bfd_section)
53765796c8dcSSimon Schubert {
5377cf7f2e2dSJohn Marino int retval = sec_index;
53785796c8dcSSimon Schubert
53795796c8dcSSimon Schubert if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
53805796c8dcSSimon Schubert return retval;
53815796c8dcSSimon Schubert }
53825796c8dcSSimon Schubert
5383cf7f2e2dSJohn Marino if (sec_index == SHN_BAD)
53845796c8dcSSimon Schubert bfd_set_error (bfd_error_nonrepresentable_section);
53855796c8dcSSimon Schubert
5386cf7f2e2dSJohn Marino return sec_index;
53875796c8dcSSimon Schubert }
53885796c8dcSSimon Schubert
53895796c8dcSSimon Schubert /* Given a BFD symbol, return the index in the ELF symbol table, or -1
53905796c8dcSSimon Schubert on error. */
53915796c8dcSSimon Schubert
53925796c8dcSSimon Schubert int
_bfd_elf_symbol_from_bfd_symbol(bfd * abfd,asymbol ** asym_ptr_ptr)53935796c8dcSSimon Schubert _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
53945796c8dcSSimon Schubert {
53955796c8dcSSimon Schubert asymbol *asym_ptr = *asym_ptr_ptr;
53965796c8dcSSimon Schubert int idx;
53975796c8dcSSimon Schubert flagword flags = asym_ptr->flags;
53985796c8dcSSimon Schubert
53995796c8dcSSimon Schubert /* When gas creates relocations against local labels, it creates its
54005796c8dcSSimon Schubert own symbol for the section, but does put the symbol into the
54015796c8dcSSimon Schubert symbol chain, so udata is 0. When the linker is generating
54025796c8dcSSimon Schubert relocatable output, this section symbol may be for one of the
54035796c8dcSSimon Schubert input sections rather than the output section. */
54045796c8dcSSimon Schubert if (asym_ptr->udata.i == 0
54055796c8dcSSimon Schubert && (flags & BSF_SECTION_SYM)
54065796c8dcSSimon Schubert && asym_ptr->section)
54075796c8dcSSimon Schubert {
54085796c8dcSSimon Schubert asection *sec;
54095796c8dcSSimon Schubert int indx;
54105796c8dcSSimon Schubert
54115796c8dcSSimon Schubert sec = asym_ptr->section;
54125796c8dcSSimon Schubert if (sec->owner != abfd && sec->output_section != NULL)
54135796c8dcSSimon Schubert sec = sec->output_section;
54145796c8dcSSimon Schubert if (sec->owner == abfd
54155796c8dcSSimon Schubert && (indx = sec->index) < elf_num_section_syms (abfd)
54165796c8dcSSimon Schubert && elf_section_syms (abfd)[indx] != NULL)
54175796c8dcSSimon Schubert asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
54185796c8dcSSimon Schubert }
54195796c8dcSSimon Schubert
54205796c8dcSSimon Schubert idx = asym_ptr->udata.i;
54215796c8dcSSimon Schubert
54225796c8dcSSimon Schubert if (idx == 0)
54235796c8dcSSimon Schubert {
54245796c8dcSSimon Schubert /* This case can occur when using --strip-symbol on a symbol
54255796c8dcSSimon Schubert which is used in a relocation entry. */
54265796c8dcSSimon Schubert (*_bfd_error_handler)
54275796c8dcSSimon Schubert (_("%B: symbol `%s' required but not present"),
54285796c8dcSSimon Schubert abfd, bfd_asymbol_name (asym_ptr));
54295796c8dcSSimon Schubert bfd_set_error (bfd_error_no_symbols);
54305796c8dcSSimon Schubert return -1;
54315796c8dcSSimon Schubert }
54325796c8dcSSimon Schubert
54335796c8dcSSimon Schubert #if DEBUG & 4
54345796c8dcSSimon Schubert {
54355796c8dcSSimon Schubert fprintf (stderr,
5436c50c785cSJohn Marino "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx\n",
5437c50c785cSJohn Marino (long) asym_ptr, asym_ptr->name, idx, (long) flags);
54385796c8dcSSimon Schubert fflush (stderr);
54395796c8dcSSimon Schubert }
54405796c8dcSSimon Schubert #endif
54415796c8dcSSimon Schubert
54425796c8dcSSimon Schubert return idx;
54435796c8dcSSimon Schubert }
54445796c8dcSSimon Schubert
54455796c8dcSSimon Schubert /* Rewrite program header information. */
54465796c8dcSSimon Schubert
54475796c8dcSSimon Schubert static bfd_boolean
rewrite_elf_program_header(bfd * ibfd,bfd * obfd)54485796c8dcSSimon Schubert rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
54495796c8dcSSimon Schubert {
54505796c8dcSSimon Schubert Elf_Internal_Ehdr *iehdr;
54515796c8dcSSimon Schubert struct elf_segment_map *map;
54525796c8dcSSimon Schubert struct elf_segment_map *map_first;
54535796c8dcSSimon Schubert struct elf_segment_map **pointer_to_map;
54545796c8dcSSimon Schubert Elf_Internal_Phdr *segment;
54555796c8dcSSimon Schubert asection *section;
54565796c8dcSSimon Schubert unsigned int i;
54575796c8dcSSimon Schubert unsigned int num_segments;
54585796c8dcSSimon Schubert bfd_boolean phdr_included = FALSE;
54595796c8dcSSimon Schubert bfd_boolean p_paddr_valid;
54605796c8dcSSimon Schubert bfd_vma maxpagesize;
54615796c8dcSSimon Schubert struct elf_segment_map *phdr_adjust_seg = NULL;
54625796c8dcSSimon Schubert unsigned int phdr_adjust_num = 0;
54635796c8dcSSimon Schubert const struct elf_backend_data *bed;
54645796c8dcSSimon Schubert
54655796c8dcSSimon Schubert bed = get_elf_backend_data (ibfd);
54665796c8dcSSimon Schubert iehdr = elf_elfheader (ibfd);
54675796c8dcSSimon Schubert
54685796c8dcSSimon Schubert map_first = NULL;
54695796c8dcSSimon Schubert pointer_to_map = &map_first;
54705796c8dcSSimon Schubert
54715796c8dcSSimon Schubert num_segments = elf_elfheader (ibfd)->e_phnum;
54725796c8dcSSimon Schubert maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
54735796c8dcSSimon Schubert
54745796c8dcSSimon Schubert /* Returns the end address of the segment + 1. */
54755796c8dcSSimon Schubert #define SEGMENT_END(segment, start) \
54765796c8dcSSimon Schubert (start + (segment->p_memsz > segment->p_filesz \
54775796c8dcSSimon Schubert ? segment->p_memsz : segment->p_filesz))
54785796c8dcSSimon Schubert
54795796c8dcSSimon Schubert #define SECTION_SIZE(section, segment) \
54805796c8dcSSimon Schubert (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \
54815796c8dcSSimon Schubert != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \
54825796c8dcSSimon Schubert ? section->size : 0)
54835796c8dcSSimon Schubert
54845796c8dcSSimon Schubert /* Returns TRUE if the given section is contained within
54855796c8dcSSimon Schubert the given segment. VMA addresses are compared. */
54865796c8dcSSimon Schubert #define IS_CONTAINED_BY_VMA(section, segment) \
54875796c8dcSSimon Schubert (section->vma >= segment->p_vaddr \
54885796c8dcSSimon Schubert && (section->vma + SECTION_SIZE (section, segment) \
54895796c8dcSSimon Schubert <= (SEGMENT_END (segment, segment->p_vaddr))))
54905796c8dcSSimon Schubert
54915796c8dcSSimon Schubert /* Returns TRUE if the given section is contained within
54925796c8dcSSimon Schubert the given segment. LMA addresses are compared. */
54935796c8dcSSimon Schubert #define IS_CONTAINED_BY_LMA(section, segment, base) \
54945796c8dcSSimon Schubert (section->lma >= base \
54955796c8dcSSimon Schubert && (section->lma + SECTION_SIZE (section, segment) \
54965796c8dcSSimon Schubert <= SEGMENT_END (segment, base)))
54975796c8dcSSimon Schubert
54985796c8dcSSimon Schubert /* Handle PT_NOTE segment. */
54995796c8dcSSimon Schubert #define IS_NOTE(p, s) \
55005796c8dcSSimon Schubert (p->p_type == PT_NOTE \
55015796c8dcSSimon Schubert && elf_section_type (s) == SHT_NOTE \
55025796c8dcSSimon Schubert && (bfd_vma) s->filepos >= p->p_offset \
55035796c8dcSSimon Schubert && ((bfd_vma) s->filepos + s->size \
55045796c8dcSSimon Schubert <= p->p_offset + p->p_filesz))
55055796c8dcSSimon Schubert
55065796c8dcSSimon Schubert /* Special case: corefile "NOTE" section containing regs, prpsinfo
55075796c8dcSSimon Schubert etc. */
55085796c8dcSSimon Schubert #define IS_COREFILE_NOTE(p, s) \
55095796c8dcSSimon Schubert (IS_NOTE (p, s) \
55105796c8dcSSimon Schubert && bfd_get_format (ibfd) == bfd_core \
55115796c8dcSSimon Schubert && s->vma == 0 \
55125796c8dcSSimon Schubert && s->lma == 0)
55135796c8dcSSimon Schubert
55145796c8dcSSimon Schubert /* The complicated case when p_vaddr is 0 is to handle the Solaris
55155796c8dcSSimon Schubert linker, which generates a PT_INTERP section with p_vaddr and
55165796c8dcSSimon Schubert p_memsz set to 0. */
55175796c8dcSSimon Schubert #define IS_SOLARIS_PT_INTERP(p, s) \
55185796c8dcSSimon Schubert (p->p_vaddr == 0 \
55195796c8dcSSimon Schubert && p->p_paddr == 0 \
55205796c8dcSSimon Schubert && p->p_memsz == 0 \
55215796c8dcSSimon Schubert && p->p_filesz > 0 \
55225796c8dcSSimon Schubert && (s->flags & SEC_HAS_CONTENTS) != 0 \
55235796c8dcSSimon Schubert && s->size > 0 \
55245796c8dcSSimon Schubert && (bfd_vma) s->filepos >= p->p_offset \
55255796c8dcSSimon Schubert && ((bfd_vma) s->filepos + s->size \
55265796c8dcSSimon Schubert <= p->p_offset + p->p_filesz))
55275796c8dcSSimon Schubert
55285796c8dcSSimon Schubert /* Decide if the given section should be included in the given segment.
55295796c8dcSSimon Schubert A section will be included if:
55305796c8dcSSimon Schubert 1. It is within the address space of the segment -- we use the LMA
55315796c8dcSSimon Schubert if that is set for the segment and the VMA otherwise,
55325796c8dcSSimon Schubert 2. It is an allocated section or a NOTE section in a PT_NOTE
55335796c8dcSSimon Schubert segment.
55345796c8dcSSimon Schubert 3. There is an output section associated with it,
55355796c8dcSSimon Schubert 4. The section has not already been allocated to a previous segment.
55365796c8dcSSimon Schubert 5. PT_GNU_STACK segments do not include any sections.
55375796c8dcSSimon Schubert 6. PT_TLS segment includes only SHF_TLS sections.
55385796c8dcSSimon Schubert 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
55395796c8dcSSimon Schubert 8. PT_DYNAMIC should not contain empty sections at the beginning
55405796c8dcSSimon Schubert (with the possible exception of .dynamic). */
55415796c8dcSSimon Schubert #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \
55425796c8dcSSimon Schubert ((((segment->p_paddr \
55435796c8dcSSimon Schubert ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
55445796c8dcSSimon Schubert : IS_CONTAINED_BY_VMA (section, segment)) \
55455796c8dcSSimon Schubert && (section->flags & SEC_ALLOC) != 0) \
55465796c8dcSSimon Schubert || IS_NOTE (segment, section)) \
55475796c8dcSSimon Schubert && segment->p_type != PT_GNU_STACK \
55485796c8dcSSimon Schubert && (segment->p_type != PT_TLS \
55495796c8dcSSimon Schubert || (section->flags & SEC_THREAD_LOCAL)) \
55505796c8dcSSimon Schubert && (segment->p_type == PT_LOAD \
55515796c8dcSSimon Schubert || segment->p_type == PT_TLS \
55525796c8dcSSimon Schubert || (section->flags & SEC_THREAD_LOCAL) == 0) \
55535796c8dcSSimon Schubert && (segment->p_type != PT_DYNAMIC \
55545796c8dcSSimon Schubert || SECTION_SIZE (section, segment) > 0 \
55555796c8dcSSimon Schubert || (segment->p_paddr \
55565796c8dcSSimon Schubert ? segment->p_paddr != section->lma \
55575796c8dcSSimon Schubert : segment->p_vaddr != section->vma) \
55585796c8dcSSimon Schubert || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \
55595796c8dcSSimon Schubert == 0)) \
55605796c8dcSSimon Schubert && !section->segment_mark)
55615796c8dcSSimon Schubert
55625796c8dcSSimon Schubert /* If the output section of a section in the input segment is NULL,
55635796c8dcSSimon Schubert it is removed from the corresponding output segment. */
55645796c8dcSSimon Schubert #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
55655796c8dcSSimon Schubert (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \
55665796c8dcSSimon Schubert && section->output_section != NULL)
55675796c8dcSSimon Schubert
55685796c8dcSSimon Schubert /* Returns TRUE iff seg1 starts after the end of seg2. */
55695796c8dcSSimon Schubert #define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \
55705796c8dcSSimon Schubert (seg1->field >= SEGMENT_END (seg2, seg2->field))
55715796c8dcSSimon Schubert
55725796c8dcSSimon Schubert /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
55735796c8dcSSimon Schubert their VMA address ranges and their LMA address ranges overlap.
55745796c8dcSSimon Schubert It is possible to have overlapping VMA ranges without overlapping LMA
55755796c8dcSSimon Schubert ranges. RedBoot images for example can have both .data and .bss mapped
55765796c8dcSSimon Schubert to the same VMA range, but with the .data section mapped to a different
55775796c8dcSSimon Schubert LMA. */
55785796c8dcSSimon Schubert #define SEGMENT_OVERLAPS(seg1, seg2) \
55795796c8dcSSimon Schubert ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \
55805796c8dcSSimon Schubert || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \
55815796c8dcSSimon Schubert && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \
55825796c8dcSSimon Schubert || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
55835796c8dcSSimon Schubert
55845796c8dcSSimon Schubert /* Initialise the segment mark field. */
55855796c8dcSSimon Schubert for (section = ibfd->sections; section != NULL; section = section->next)
55865796c8dcSSimon Schubert section->segment_mark = FALSE;
55875796c8dcSSimon Schubert
55885796c8dcSSimon Schubert /* The Solaris linker creates program headers in which all the
55895796c8dcSSimon Schubert p_paddr fields are zero. When we try to objcopy or strip such a
55905796c8dcSSimon Schubert file, we get confused. Check for this case, and if we find it
55915796c8dcSSimon Schubert don't set the p_paddr_valid fields. */
55925796c8dcSSimon Schubert p_paddr_valid = FALSE;
55935796c8dcSSimon Schubert for (i = 0, segment = elf_tdata (ibfd)->phdr;
55945796c8dcSSimon Schubert i < num_segments;
55955796c8dcSSimon Schubert i++, segment++)
55965796c8dcSSimon Schubert if (segment->p_paddr != 0)
55975796c8dcSSimon Schubert {
55985796c8dcSSimon Schubert p_paddr_valid = TRUE;
55995796c8dcSSimon Schubert break;
56005796c8dcSSimon Schubert }
56015796c8dcSSimon Schubert
56025796c8dcSSimon Schubert /* Scan through the segments specified in the program header
56035796c8dcSSimon Schubert of the input BFD. For this first scan we look for overlaps
56045796c8dcSSimon Schubert in the loadable segments. These can be created by weird
56055796c8dcSSimon Schubert parameters to objcopy. Also, fix some solaris weirdness. */
56065796c8dcSSimon Schubert for (i = 0, segment = elf_tdata (ibfd)->phdr;
56075796c8dcSSimon Schubert i < num_segments;
56085796c8dcSSimon Schubert i++, segment++)
56095796c8dcSSimon Schubert {
56105796c8dcSSimon Schubert unsigned int j;
56115796c8dcSSimon Schubert Elf_Internal_Phdr *segment2;
56125796c8dcSSimon Schubert
56135796c8dcSSimon Schubert if (segment->p_type == PT_INTERP)
56145796c8dcSSimon Schubert for (section = ibfd->sections; section; section = section->next)
56155796c8dcSSimon Schubert if (IS_SOLARIS_PT_INTERP (segment, section))
56165796c8dcSSimon Schubert {
56175796c8dcSSimon Schubert /* Mininal change so that the normal section to segment
56185796c8dcSSimon Schubert assignment code will work. */
56195796c8dcSSimon Schubert segment->p_vaddr = section->vma;
56205796c8dcSSimon Schubert break;
56215796c8dcSSimon Schubert }
56225796c8dcSSimon Schubert
56235796c8dcSSimon Schubert if (segment->p_type != PT_LOAD)
56245796c8dcSSimon Schubert {
56255796c8dcSSimon Schubert /* Remove PT_GNU_RELRO segment. */
56265796c8dcSSimon Schubert if (segment->p_type == PT_GNU_RELRO)
56275796c8dcSSimon Schubert segment->p_type = PT_NULL;
56285796c8dcSSimon Schubert continue;
56295796c8dcSSimon Schubert }
56305796c8dcSSimon Schubert
56315796c8dcSSimon Schubert /* Determine if this segment overlaps any previous segments. */
56325796c8dcSSimon Schubert for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
56335796c8dcSSimon Schubert {
56345796c8dcSSimon Schubert bfd_signed_vma extra_length;
56355796c8dcSSimon Schubert
56365796c8dcSSimon Schubert if (segment2->p_type != PT_LOAD
56375796c8dcSSimon Schubert || !SEGMENT_OVERLAPS (segment, segment2))
56385796c8dcSSimon Schubert continue;
56395796c8dcSSimon Schubert
56405796c8dcSSimon Schubert /* Merge the two segments together. */
56415796c8dcSSimon Schubert if (segment2->p_vaddr < segment->p_vaddr)
56425796c8dcSSimon Schubert {
56435796c8dcSSimon Schubert /* Extend SEGMENT2 to include SEGMENT and then delete
56445796c8dcSSimon Schubert SEGMENT. */
56455796c8dcSSimon Schubert extra_length = (SEGMENT_END (segment, segment->p_vaddr)
56465796c8dcSSimon Schubert - SEGMENT_END (segment2, segment2->p_vaddr));
56475796c8dcSSimon Schubert
56485796c8dcSSimon Schubert if (extra_length > 0)
56495796c8dcSSimon Schubert {
56505796c8dcSSimon Schubert segment2->p_memsz += extra_length;
56515796c8dcSSimon Schubert segment2->p_filesz += extra_length;
56525796c8dcSSimon Schubert }
56535796c8dcSSimon Schubert
56545796c8dcSSimon Schubert segment->p_type = PT_NULL;
56555796c8dcSSimon Schubert
56565796c8dcSSimon Schubert /* Since we have deleted P we must restart the outer loop. */
56575796c8dcSSimon Schubert i = 0;
56585796c8dcSSimon Schubert segment = elf_tdata (ibfd)->phdr;
56595796c8dcSSimon Schubert break;
56605796c8dcSSimon Schubert }
56615796c8dcSSimon Schubert else
56625796c8dcSSimon Schubert {
56635796c8dcSSimon Schubert /* Extend SEGMENT to include SEGMENT2 and then delete
56645796c8dcSSimon Schubert SEGMENT2. */
56655796c8dcSSimon Schubert extra_length = (SEGMENT_END (segment2, segment2->p_vaddr)
56665796c8dcSSimon Schubert - SEGMENT_END (segment, segment->p_vaddr));
56675796c8dcSSimon Schubert
56685796c8dcSSimon Schubert if (extra_length > 0)
56695796c8dcSSimon Schubert {
56705796c8dcSSimon Schubert segment->p_memsz += extra_length;
56715796c8dcSSimon Schubert segment->p_filesz += extra_length;
56725796c8dcSSimon Schubert }
56735796c8dcSSimon Schubert
56745796c8dcSSimon Schubert segment2->p_type = PT_NULL;
56755796c8dcSSimon Schubert }
56765796c8dcSSimon Schubert }
56775796c8dcSSimon Schubert }
56785796c8dcSSimon Schubert
56795796c8dcSSimon Schubert /* The second scan attempts to assign sections to segments. */
56805796c8dcSSimon Schubert for (i = 0, segment = elf_tdata (ibfd)->phdr;
56815796c8dcSSimon Schubert i < num_segments;
56825796c8dcSSimon Schubert i++, segment++)
56835796c8dcSSimon Schubert {
56845796c8dcSSimon Schubert unsigned int section_count;
56855796c8dcSSimon Schubert asection **sections;
56865796c8dcSSimon Schubert asection *output_section;
56875796c8dcSSimon Schubert unsigned int isec;
56885796c8dcSSimon Schubert bfd_vma matching_lma;
56895796c8dcSSimon Schubert bfd_vma suggested_lma;
56905796c8dcSSimon Schubert unsigned int j;
56915796c8dcSSimon Schubert bfd_size_type amt;
56925796c8dcSSimon Schubert asection *first_section;
56935796c8dcSSimon Schubert bfd_boolean first_matching_lma;
56945796c8dcSSimon Schubert bfd_boolean first_suggested_lma;
56955796c8dcSSimon Schubert
56965796c8dcSSimon Schubert if (segment->p_type == PT_NULL)
56975796c8dcSSimon Schubert continue;
56985796c8dcSSimon Schubert
56995796c8dcSSimon Schubert first_section = NULL;
57005796c8dcSSimon Schubert /* Compute how many sections might be placed into this segment. */
57015796c8dcSSimon Schubert for (section = ibfd->sections, section_count = 0;
57025796c8dcSSimon Schubert section != NULL;
57035796c8dcSSimon Schubert section = section->next)
57045796c8dcSSimon Schubert {
57055796c8dcSSimon Schubert /* Find the first section in the input segment, which may be
57065796c8dcSSimon Schubert removed from the corresponding output segment. */
57075796c8dcSSimon Schubert if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
57085796c8dcSSimon Schubert {
57095796c8dcSSimon Schubert if (first_section == NULL)
57105796c8dcSSimon Schubert first_section = section;
57115796c8dcSSimon Schubert if (section->output_section != NULL)
57125796c8dcSSimon Schubert ++section_count;
57135796c8dcSSimon Schubert }
57145796c8dcSSimon Schubert }
57155796c8dcSSimon Schubert
57165796c8dcSSimon Schubert /* Allocate a segment map big enough to contain
57175796c8dcSSimon Schubert all of the sections we have selected. */
57185796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
57195796c8dcSSimon Schubert amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
57205796c8dcSSimon Schubert map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
57215796c8dcSSimon Schubert if (map == NULL)
57225796c8dcSSimon Schubert return FALSE;
57235796c8dcSSimon Schubert
57245796c8dcSSimon Schubert /* Initialise the fields of the segment map. Default to
57255796c8dcSSimon Schubert using the physical address of the segment in the input BFD. */
57265796c8dcSSimon Schubert map->next = NULL;
57275796c8dcSSimon Schubert map->p_type = segment->p_type;
57285796c8dcSSimon Schubert map->p_flags = segment->p_flags;
57295796c8dcSSimon Schubert map->p_flags_valid = 1;
57305796c8dcSSimon Schubert
57315796c8dcSSimon Schubert /* If the first section in the input segment is removed, there is
57325796c8dcSSimon Schubert no need to preserve segment physical address in the corresponding
57335796c8dcSSimon Schubert output segment. */
57345796c8dcSSimon Schubert if (!first_section || first_section->output_section != NULL)
57355796c8dcSSimon Schubert {
57365796c8dcSSimon Schubert map->p_paddr = segment->p_paddr;
57375796c8dcSSimon Schubert map->p_paddr_valid = p_paddr_valid;
57385796c8dcSSimon Schubert }
57395796c8dcSSimon Schubert
57405796c8dcSSimon Schubert /* Determine if this segment contains the ELF file header
57415796c8dcSSimon Schubert and if it contains the program headers themselves. */
57425796c8dcSSimon Schubert map->includes_filehdr = (segment->p_offset == 0
57435796c8dcSSimon Schubert && segment->p_filesz >= iehdr->e_ehsize);
57445796c8dcSSimon Schubert map->includes_phdrs = 0;
57455796c8dcSSimon Schubert
57465796c8dcSSimon Schubert if (!phdr_included || segment->p_type != PT_LOAD)
57475796c8dcSSimon Schubert {
57485796c8dcSSimon Schubert map->includes_phdrs =
57495796c8dcSSimon Schubert (segment->p_offset <= (bfd_vma) iehdr->e_phoff
57505796c8dcSSimon Schubert && (segment->p_offset + segment->p_filesz
57515796c8dcSSimon Schubert >= ((bfd_vma) iehdr->e_phoff
57525796c8dcSSimon Schubert + iehdr->e_phnum * iehdr->e_phentsize)));
57535796c8dcSSimon Schubert
57545796c8dcSSimon Schubert if (segment->p_type == PT_LOAD && map->includes_phdrs)
57555796c8dcSSimon Schubert phdr_included = TRUE;
57565796c8dcSSimon Schubert }
57575796c8dcSSimon Schubert
57585796c8dcSSimon Schubert if (section_count == 0)
57595796c8dcSSimon Schubert {
57605796c8dcSSimon Schubert /* Special segments, such as the PT_PHDR segment, may contain
57615796c8dcSSimon Schubert no sections, but ordinary, loadable segments should contain
57625796c8dcSSimon Schubert something. They are allowed by the ELF spec however, so only
57635796c8dcSSimon Schubert a warning is produced. */
57645796c8dcSSimon Schubert if (segment->p_type == PT_LOAD)
57655796c8dcSSimon Schubert (*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
57665796c8dcSSimon Schubert " detected, is this intentional ?\n"),
57675796c8dcSSimon Schubert ibfd);
57685796c8dcSSimon Schubert
57695796c8dcSSimon Schubert map->count = 0;
57705796c8dcSSimon Schubert *pointer_to_map = map;
57715796c8dcSSimon Schubert pointer_to_map = &map->next;
57725796c8dcSSimon Schubert
57735796c8dcSSimon Schubert continue;
57745796c8dcSSimon Schubert }
57755796c8dcSSimon Schubert
57765796c8dcSSimon Schubert /* Now scan the sections in the input BFD again and attempt
57775796c8dcSSimon Schubert to add their corresponding output sections to the segment map.
57785796c8dcSSimon Schubert The problem here is how to handle an output section which has
57795796c8dcSSimon Schubert been moved (ie had its LMA changed). There are four possibilities:
57805796c8dcSSimon Schubert
57815796c8dcSSimon Schubert 1. None of the sections have been moved.
57825796c8dcSSimon Schubert In this case we can continue to use the segment LMA from the
57835796c8dcSSimon Schubert input BFD.
57845796c8dcSSimon Schubert
57855796c8dcSSimon Schubert 2. All of the sections have been moved by the same amount.
57865796c8dcSSimon Schubert In this case we can change the segment's LMA to match the LMA
57875796c8dcSSimon Schubert of the first section.
57885796c8dcSSimon Schubert
57895796c8dcSSimon Schubert 3. Some of the sections have been moved, others have not.
57905796c8dcSSimon Schubert In this case those sections which have not been moved can be
57915796c8dcSSimon Schubert placed in the current segment which will have to have its size,
57925796c8dcSSimon Schubert and possibly its LMA changed, and a new segment or segments will
57935796c8dcSSimon Schubert have to be created to contain the other sections.
57945796c8dcSSimon Schubert
57955796c8dcSSimon Schubert 4. The sections have been moved, but not by the same amount.
57965796c8dcSSimon Schubert In this case we can change the segment's LMA to match the LMA
57975796c8dcSSimon Schubert of the first section and we will have to create a new segment
57985796c8dcSSimon Schubert or segments to contain the other sections.
57995796c8dcSSimon Schubert
58005796c8dcSSimon Schubert In order to save time, we allocate an array to hold the section
58015796c8dcSSimon Schubert pointers that we are interested in. As these sections get assigned
58025796c8dcSSimon Schubert to a segment, they are removed from this array. */
58035796c8dcSSimon Schubert
58045796c8dcSSimon Schubert sections = (asection **) bfd_malloc2 (section_count, sizeof (asection *));
58055796c8dcSSimon Schubert if (sections == NULL)
58065796c8dcSSimon Schubert return FALSE;
58075796c8dcSSimon Schubert
58085796c8dcSSimon Schubert /* Step One: Scan for segment vs section LMA conflicts.
58095796c8dcSSimon Schubert Also add the sections to the section array allocated above.
58105796c8dcSSimon Schubert Also add the sections to the current segment. In the common
58115796c8dcSSimon Schubert case, where the sections have not been moved, this means that
58125796c8dcSSimon Schubert we have completely filled the segment, and there is nothing
58135796c8dcSSimon Schubert more to do. */
58145796c8dcSSimon Schubert isec = 0;
58155796c8dcSSimon Schubert matching_lma = 0;
58165796c8dcSSimon Schubert suggested_lma = 0;
58175796c8dcSSimon Schubert first_matching_lma = TRUE;
58185796c8dcSSimon Schubert first_suggested_lma = TRUE;
58195796c8dcSSimon Schubert
58205796c8dcSSimon Schubert for (section = ibfd->sections;
58215796c8dcSSimon Schubert section != NULL;
58225796c8dcSSimon Schubert section = section->next)
58235796c8dcSSimon Schubert if (section == first_section)
58245796c8dcSSimon Schubert break;
58255796c8dcSSimon Schubert
58265796c8dcSSimon Schubert for (j = 0; section != NULL; section = section->next)
58275796c8dcSSimon Schubert {
58285796c8dcSSimon Schubert if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
58295796c8dcSSimon Schubert {
58305796c8dcSSimon Schubert output_section = section->output_section;
58315796c8dcSSimon Schubert
58325796c8dcSSimon Schubert sections[j++] = section;
58335796c8dcSSimon Schubert
58345796c8dcSSimon Schubert /* The Solaris native linker always sets p_paddr to 0.
58355796c8dcSSimon Schubert We try to catch that case here, and set it to the
58365796c8dcSSimon Schubert correct value. Note - some backends require that
58375796c8dcSSimon Schubert p_paddr be left as zero. */
58385796c8dcSSimon Schubert if (!p_paddr_valid
58395796c8dcSSimon Schubert && segment->p_vaddr != 0
58405796c8dcSSimon Schubert && !bed->want_p_paddr_set_to_zero
58415796c8dcSSimon Schubert && isec == 0
58425796c8dcSSimon Schubert && output_section->lma != 0
58435796c8dcSSimon Schubert && output_section->vma == (segment->p_vaddr
58445796c8dcSSimon Schubert + (map->includes_filehdr
58455796c8dcSSimon Schubert ? iehdr->e_ehsize
58465796c8dcSSimon Schubert : 0)
58475796c8dcSSimon Schubert + (map->includes_phdrs
58485796c8dcSSimon Schubert ? (iehdr->e_phnum
58495796c8dcSSimon Schubert * iehdr->e_phentsize)
58505796c8dcSSimon Schubert : 0)))
58515796c8dcSSimon Schubert map->p_paddr = segment->p_vaddr;
58525796c8dcSSimon Schubert
58535796c8dcSSimon Schubert /* Match up the physical address of the segment with the
58545796c8dcSSimon Schubert LMA address of the output section. */
58555796c8dcSSimon Schubert if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
58565796c8dcSSimon Schubert || IS_COREFILE_NOTE (segment, section)
58575796c8dcSSimon Schubert || (bed->want_p_paddr_set_to_zero
58585796c8dcSSimon Schubert && IS_CONTAINED_BY_VMA (output_section, segment)))
58595796c8dcSSimon Schubert {
58605796c8dcSSimon Schubert if (first_matching_lma || output_section->lma < matching_lma)
58615796c8dcSSimon Schubert {
58625796c8dcSSimon Schubert matching_lma = output_section->lma;
58635796c8dcSSimon Schubert first_matching_lma = FALSE;
58645796c8dcSSimon Schubert }
58655796c8dcSSimon Schubert
58665796c8dcSSimon Schubert /* We assume that if the section fits within the segment
58675796c8dcSSimon Schubert then it does not overlap any other section within that
58685796c8dcSSimon Schubert segment. */
58695796c8dcSSimon Schubert map->sections[isec++] = output_section;
58705796c8dcSSimon Schubert }
58715796c8dcSSimon Schubert else if (first_suggested_lma)
58725796c8dcSSimon Schubert {
58735796c8dcSSimon Schubert suggested_lma = output_section->lma;
58745796c8dcSSimon Schubert first_suggested_lma = FALSE;
58755796c8dcSSimon Schubert }
58765796c8dcSSimon Schubert
58775796c8dcSSimon Schubert if (j == section_count)
58785796c8dcSSimon Schubert break;
58795796c8dcSSimon Schubert }
58805796c8dcSSimon Schubert }
58815796c8dcSSimon Schubert
58825796c8dcSSimon Schubert BFD_ASSERT (j == section_count);
58835796c8dcSSimon Schubert
58845796c8dcSSimon Schubert /* Step Two: Adjust the physical address of the current segment,
58855796c8dcSSimon Schubert if necessary. */
58865796c8dcSSimon Schubert if (isec == section_count)
58875796c8dcSSimon Schubert {
58885796c8dcSSimon Schubert /* All of the sections fitted within the segment as currently
58895796c8dcSSimon Schubert specified. This is the default case. Add the segment to
58905796c8dcSSimon Schubert the list of built segments and carry on to process the next
58915796c8dcSSimon Schubert program header in the input BFD. */
58925796c8dcSSimon Schubert map->count = section_count;
58935796c8dcSSimon Schubert *pointer_to_map = map;
58945796c8dcSSimon Schubert pointer_to_map = &map->next;
58955796c8dcSSimon Schubert
58965796c8dcSSimon Schubert if (p_paddr_valid
58975796c8dcSSimon Schubert && !bed->want_p_paddr_set_to_zero
58985796c8dcSSimon Schubert && matching_lma != map->p_paddr
58995796c8dcSSimon Schubert && !map->includes_filehdr
59005796c8dcSSimon Schubert && !map->includes_phdrs)
59015796c8dcSSimon Schubert /* There is some padding before the first section in the
59025796c8dcSSimon Schubert segment. So, we must account for that in the output
59035796c8dcSSimon Schubert segment's vma. */
59045796c8dcSSimon Schubert map->p_vaddr_offset = matching_lma - map->p_paddr;
59055796c8dcSSimon Schubert
59065796c8dcSSimon Schubert free (sections);
59075796c8dcSSimon Schubert continue;
59085796c8dcSSimon Schubert }
59095796c8dcSSimon Schubert else
59105796c8dcSSimon Schubert {
59115796c8dcSSimon Schubert if (!first_matching_lma)
59125796c8dcSSimon Schubert {
59135796c8dcSSimon Schubert /* At least one section fits inside the current segment.
59145796c8dcSSimon Schubert Keep it, but modify its physical address to match the
59155796c8dcSSimon Schubert LMA of the first section that fitted. */
59165796c8dcSSimon Schubert map->p_paddr = matching_lma;
59175796c8dcSSimon Schubert }
59185796c8dcSSimon Schubert else
59195796c8dcSSimon Schubert {
59205796c8dcSSimon Schubert /* None of the sections fitted inside the current segment.
59215796c8dcSSimon Schubert Change the current segment's physical address to match
59225796c8dcSSimon Schubert the LMA of the first section. */
59235796c8dcSSimon Schubert map->p_paddr = suggested_lma;
59245796c8dcSSimon Schubert }
59255796c8dcSSimon Schubert
59265796c8dcSSimon Schubert /* Offset the segment physical address from the lma
59275796c8dcSSimon Schubert to allow for space taken up by elf headers. */
59285796c8dcSSimon Schubert if (map->includes_filehdr)
59295796c8dcSSimon Schubert {
59305796c8dcSSimon Schubert if (map->p_paddr >= iehdr->e_ehsize)
59315796c8dcSSimon Schubert map->p_paddr -= iehdr->e_ehsize;
59325796c8dcSSimon Schubert else
59335796c8dcSSimon Schubert {
59345796c8dcSSimon Schubert map->includes_filehdr = FALSE;
59355796c8dcSSimon Schubert map->includes_phdrs = FALSE;
59365796c8dcSSimon Schubert }
59375796c8dcSSimon Schubert }
59385796c8dcSSimon Schubert
59395796c8dcSSimon Schubert if (map->includes_phdrs)
59405796c8dcSSimon Schubert {
59415796c8dcSSimon Schubert if (map->p_paddr >= iehdr->e_phnum * iehdr->e_phentsize)
59425796c8dcSSimon Schubert {
59435796c8dcSSimon Schubert map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
59445796c8dcSSimon Schubert
59455796c8dcSSimon Schubert /* iehdr->e_phnum is just an estimate of the number
59465796c8dcSSimon Schubert of program headers that we will need. Make a note
59475796c8dcSSimon Schubert here of the number we used and the segment we chose
59485796c8dcSSimon Schubert to hold these headers, so that we can adjust the
59495796c8dcSSimon Schubert offset when we know the correct value. */
59505796c8dcSSimon Schubert phdr_adjust_num = iehdr->e_phnum;
59515796c8dcSSimon Schubert phdr_adjust_seg = map;
59525796c8dcSSimon Schubert }
59535796c8dcSSimon Schubert else
59545796c8dcSSimon Schubert map->includes_phdrs = FALSE;
59555796c8dcSSimon Schubert }
59565796c8dcSSimon Schubert }
59575796c8dcSSimon Schubert
59585796c8dcSSimon Schubert /* Step Three: Loop over the sections again, this time assigning
59595796c8dcSSimon Schubert those that fit to the current segment and removing them from the
59605796c8dcSSimon Schubert sections array; but making sure not to leave large gaps. Once all
59615796c8dcSSimon Schubert possible sections have been assigned to the current segment it is
59625796c8dcSSimon Schubert added to the list of built segments and if sections still remain
59635796c8dcSSimon Schubert to be assigned, a new segment is constructed before repeating
59645796c8dcSSimon Schubert the loop. */
59655796c8dcSSimon Schubert isec = 0;
59665796c8dcSSimon Schubert do
59675796c8dcSSimon Schubert {
59685796c8dcSSimon Schubert map->count = 0;
59695796c8dcSSimon Schubert suggested_lma = 0;
59705796c8dcSSimon Schubert first_suggested_lma = TRUE;
59715796c8dcSSimon Schubert
59725796c8dcSSimon Schubert /* Fill the current segment with sections that fit. */
59735796c8dcSSimon Schubert for (j = 0; j < section_count; j++)
59745796c8dcSSimon Schubert {
59755796c8dcSSimon Schubert section = sections[j];
59765796c8dcSSimon Schubert
59775796c8dcSSimon Schubert if (section == NULL)
59785796c8dcSSimon Schubert continue;
59795796c8dcSSimon Schubert
59805796c8dcSSimon Schubert output_section = section->output_section;
59815796c8dcSSimon Schubert
59825796c8dcSSimon Schubert BFD_ASSERT (output_section != NULL);
59835796c8dcSSimon Schubert
59845796c8dcSSimon Schubert if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
59855796c8dcSSimon Schubert || IS_COREFILE_NOTE (segment, section))
59865796c8dcSSimon Schubert {
59875796c8dcSSimon Schubert if (map->count == 0)
59885796c8dcSSimon Schubert {
59895796c8dcSSimon Schubert /* If the first section in a segment does not start at
59905796c8dcSSimon Schubert the beginning of the segment, then something is
59915796c8dcSSimon Schubert wrong. */
59925796c8dcSSimon Schubert if (output_section->lma
59935796c8dcSSimon Schubert != (map->p_paddr
59945796c8dcSSimon Schubert + (map->includes_filehdr ? iehdr->e_ehsize : 0)
59955796c8dcSSimon Schubert + (map->includes_phdrs
59965796c8dcSSimon Schubert ? iehdr->e_phnum * iehdr->e_phentsize
59975796c8dcSSimon Schubert : 0)))
59985796c8dcSSimon Schubert abort ();
59995796c8dcSSimon Schubert }
60005796c8dcSSimon Schubert else
60015796c8dcSSimon Schubert {
60025796c8dcSSimon Schubert asection *prev_sec;
60035796c8dcSSimon Schubert
60045796c8dcSSimon Schubert prev_sec = map->sections[map->count - 1];
60055796c8dcSSimon Schubert
60065796c8dcSSimon Schubert /* If the gap between the end of the previous section
60075796c8dcSSimon Schubert and the start of this section is more than
60085796c8dcSSimon Schubert maxpagesize then we need to start a new segment. */
60095796c8dcSSimon Schubert if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
60105796c8dcSSimon Schubert maxpagesize)
60115796c8dcSSimon Schubert < BFD_ALIGN (output_section->lma, maxpagesize))
60125796c8dcSSimon Schubert || (prev_sec->lma + prev_sec->size
60135796c8dcSSimon Schubert > output_section->lma))
60145796c8dcSSimon Schubert {
60155796c8dcSSimon Schubert if (first_suggested_lma)
60165796c8dcSSimon Schubert {
60175796c8dcSSimon Schubert suggested_lma = output_section->lma;
60185796c8dcSSimon Schubert first_suggested_lma = FALSE;
60195796c8dcSSimon Schubert }
60205796c8dcSSimon Schubert
60215796c8dcSSimon Schubert continue;
60225796c8dcSSimon Schubert }
60235796c8dcSSimon Schubert }
60245796c8dcSSimon Schubert
60255796c8dcSSimon Schubert map->sections[map->count++] = output_section;
60265796c8dcSSimon Schubert ++isec;
60275796c8dcSSimon Schubert sections[j] = NULL;
60285796c8dcSSimon Schubert section->segment_mark = TRUE;
60295796c8dcSSimon Schubert }
60305796c8dcSSimon Schubert else if (first_suggested_lma)
60315796c8dcSSimon Schubert {
60325796c8dcSSimon Schubert suggested_lma = output_section->lma;
60335796c8dcSSimon Schubert first_suggested_lma = FALSE;
60345796c8dcSSimon Schubert }
60355796c8dcSSimon Schubert }
60365796c8dcSSimon Schubert
60375796c8dcSSimon Schubert BFD_ASSERT (map->count > 0);
60385796c8dcSSimon Schubert
60395796c8dcSSimon Schubert /* Add the current segment to the list of built segments. */
60405796c8dcSSimon Schubert *pointer_to_map = map;
60415796c8dcSSimon Schubert pointer_to_map = &map->next;
60425796c8dcSSimon Schubert
60435796c8dcSSimon Schubert if (isec < section_count)
60445796c8dcSSimon Schubert {
60455796c8dcSSimon Schubert /* We still have not allocated all of the sections to
60465796c8dcSSimon Schubert segments. Create a new segment here, initialise it
60475796c8dcSSimon Schubert and carry on looping. */
60485796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
60495796c8dcSSimon Schubert amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
6050*ef5ccd6cSJohn Marino map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
60515796c8dcSSimon Schubert if (map == NULL)
60525796c8dcSSimon Schubert {
60535796c8dcSSimon Schubert free (sections);
60545796c8dcSSimon Schubert return FALSE;
60555796c8dcSSimon Schubert }
60565796c8dcSSimon Schubert
60575796c8dcSSimon Schubert /* Initialise the fields of the segment map. Set the physical
60585796c8dcSSimon Schubert physical address to the LMA of the first section that has
60595796c8dcSSimon Schubert not yet been assigned. */
60605796c8dcSSimon Schubert map->next = NULL;
60615796c8dcSSimon Schubert map->p_type = segment->p_type;
60625796c8dcSSimon Schubert map->p_flags = segment->p_flags;
60635796c8dcSSimon Schubert map->p_flags_valid = 1;
60645796c8dcSSimon Schubert map->p_paddr = suggested_lma;
60655796c8dcSSimon Schubert map->p_paddr_valid = p_paddr_valid;
60665796c8dcSSimon Schubert map->includes_filehdr = 0;
60675796c8dcSSimon Schubert map->includes_phdrs = 0;
60685796c8dcSSimon Schubert }
60695796c8dcSSimon Schubert }
60705796c8dcSSimon Schubert while (isec < section_count);
60715796c8dcSSimon Schubert
60725796c8dcSSimon Schubert free (sections);
60735796c8dcSSimon Schubert }
60745796c8dcSSimon Schubert
6075*ef5ccd6cSJohn Marino elf_seg_map (obfd) = map_first;
60765796c8dcSSimon Schubert
60775796c8dcSSimon Schubert /* If we had to estimate the number of program headers that were
60785796c8dcSSimon Schubert going to be needed, then check our estimate now and adjust
60795796c8dcSSimon Schubert the offset if necessary. */
60805796c8dcSSimon Schubert if (phdr_adjust_seg != NULL)
60815796c8dcSSimon Schubert {
60825796c8dcSSimon Schubert unsigned int count;
60835796c8dcSSimon Schubert
60845796c8dcSSimon Schubert for (count = 0, map = map_first; map != NULL; map = map->next)
60855796c8dcSSimon Schubert count++;
60865796c8dcSSimon Schubert
60875796c8dcSSimon Schubert if (count > phdr_adjust_num)
60885796c8dcSSimon Schubert phdr_adjust_seg->p_paddr
60895796c8dcSSimon Schubert -= (count - phdr_adjust_num) * iehdr->e_phentsize;
60905796c8dcSSimon Schubert }
60915796c8dcSSimon Schubert
60925796c8dcSSimon Schubert #undef SEGMENT_END
60935796c8dcSSimon Schubert #undef SECTION_SIZE
60945796c8dcSSimon Schubert #undef IS_CONTAINED_BY_VMA
60955796c8dcSSimon Schubert #undef IS_CONTAINED_BY_LMA
60965796c8dcSSimon Schubert #undef IS_NOTE
60975796c8dcSSimon Schubert #undef IS_COREFILE_NOTE
60985796c8dcSSimon Schubert #undef IS_SOLARIS_PT_INTERP
60995796c8dcSSimon Schubert #undef IS_SECTION_IN_INPUT_SEGMENT
61005796c8dcSSimon Schubert #undef INCLUDE_SECTION_IN_SEGMENT
61015796c8dcSSimon Schubert #undef SEGMENT_AFTER_SEGMENT
61025796c8dcSSimon Schubert #undef SEGMENT_OVERLAPS
61035796c8dcSSimon Schubert return TRUE;
61045796c8dcSSimon Schubert }
61055796c8dcSSimon Schubert
61065796c8dcSSimon Schubert /* Copy ELF program header information. */
61075796c8dcSSimon Schubert
61085796c8dcSSimon Schubert static bfd_boolean
copy_elf_program_header(bfd * ibfd,bfd * obfd)61095796c8dcSSimon Schubert copy_elf_program_header (bfd *ibfd, bfd *obfd)
61105796c8dcSSimon Schubert {
61115796c8dcSSimon Schubert Elf_Internal_Ehdr *iehdr;
61125796c8dcSSimon Schubert struct elf_segment_map *map;
61135796c8dcSSimon Schubert struct elf_segment_map *map_first;
61145796c8dcSSimon Schubert struct elf_segment_map **pointer_to_map;
61155796c8dcSSimon Schubert Elf_Internal_Phdr *segment;
61165796c8dcSSimon Schubert unsigned int i;
61175796c8dcSSimon Schubert unsigned int num_segments;
61185796c8dcSSimon Schubert bfd_boolean phdr_included = FALSE;
61195796c8dcSSimon Schubert bfd_boolean p_paddr_valid;
61205796c8dcSSimon Schubert
61215796c8dcSSimon Schubert iehdr = elf_elfheader (ibfd);
61225796c8dcSSimon Schubert
61235796c8dcSSimon Schubert map_first = NULL;
61245796c8dcSSimon Schubert pointer_to_map = &map_first;
61255796c8dcSSimon Schubert
61265796c8dcSSimon Schubert /* If all the segment p_paddr fields are zero, don't set
61275796c8dcSSimon Schubert map->p_paddr_valid. */
61285796c8dcSSimon Schubert p_paddr_valid = FALSE;
61295796c8dcSSimon Schubert num_segments = elf_elfheader (ibfd)->e_phnum;
61305796c8dcSSimon Schubert for (i = 0, segment = elf_tdata (ibfd)->phdr;
61315796c8dcSSimon Schubert i < num_segments;
61325796c8dcSSimon Schubert i++, segment++)
61335796c8dcSSimon Schubert if (segment->p_paddr != 0)
61345796c8dcSSimon Schubert {
61355796c8dcSSimon Schubert p_paddr_valid = TRUE;
61365796c8dcSSimon Schubert break;
61375796c8dcSSimon Schubert }
61385796c8dcSSimon Schubert
61395796c8dcSSimon Schubert for (i = 0, segment = elf_tdata (ibfd)->phdr;
61405796c8dcSSimon Schubert i < num_segments;
61415796c8dcSSimon Schubert i++, segment++)
61425796c8dcSSimon Schubert {
61435796c8dcSSimon Schubert asection *section;
61445796c8dcSSimon Schubert unsigned int section_count;
61455796c8dcSSimon Schubert bfd_size_type amt;
61465796c8dcSSimon Schubert Elf_Internal_Shdr *this_hdr;
61475796c8dcSSimon Schubert asection *first_section = NULL;
6148c50c785cSJohn Marino asection *lowest_section;
61495796c8dcSSimon Schubert
61505796c8dcSSimon Schubert /* Compute how many sections are in this segment. */
61515796c8dcSSimon Schubert for (section = ibfd->sections, section_count = 0;
61525796c8dcSSimon Schubert section != NULL;
61535796c8dcSSimon Schubert section = section->next)
61545796c8dcSSimon Schubert {
61555796c8dcSSimon Schubert this_hdr = &(elf_section_data(section)->this_hdr);
6156c50c785cSJohn Marino if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
61575796c8dcSSimon Schubert {
6158c50c785cSJohn Marino if (first_section == NULL)
6159c50c785cSJohn Marino first_section = section;
61605796c8dcSSimon Schubert section_count++;
61615796c8dcSSimon Schubert }
61625796c8dcSSimon Schubert }
61635796c8dcSSimon Schubert
61645796c8dcSSimon Schubert /* Allocate a segment map big enough to contain
61655796c8dcSSimon Schubert all of the sections we have selected. */
61665796c8dcSSimon Schubert amt = sizeof (struct elf_segment_map);
61675796c8dcSSimon Schubert if (section_count != 0)
61685796c8dcSSimon Schubert amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
61695796c8dcSSimon Schubert map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
61705796c8dcSSimon Schubert if (map == NULL)
61715796c8dcSSimon Schubert return FALSE;
61725796c8dcSSimon Schubert
61735796c8dcSSimon Schubert /* Initialize the fields of the output segment map with the
61745796c8dcSSimon Schubert input segment. */
61755796c8dcSSimon Schubert map->next = NULL;
61765796c8dcSSimon Schubert map->p_type = segment->p_type;
61775796c8dcSSimon Schubert map->p_flags = segment->p_flags;
61785796c8dcSSimon Schubert map->p_flags_valid = 1;
61795796c8dcSSimon Schubert map->p_paddr = segment->p_paddr;
61805796c8dcSSimon Schubert map->p_paddr_valid = p_paddr_valid;
61815796c8dcSSimon Schubert map->p_align = segment->p_align;
61825796c8dcSSimon Schubert map->p_align_valid = 1;
61835796c8dcSSimon Schubert map->p_vaddr_offset = 0;
61845796c8dcSSimon Schubert
6185*ef5ccd6cSJohn Marino if (map->p_type == PT_GNU_RELRO
6186*ef5ccd6cSJohn Marino || map->p_type == PT_GNU_STACK)
61875796c8dcSSimon Schubert {
61885796c8dcSSimon Schubert /* The PT_GNU_RELRO segment may contain the first a few
61895796c8dcSSimon Schubert bytes in the .got.plt section even if the whole .got.plt
61905796c8dcSSimon Schubert section isn't in the PT_GNU_RELRO segment. We won't
6191*ef5ccd6cSJohn Marino change the size of the PT_GNU_RELRO segment.
6192*ef5ccd6cSJohn Marino Similarly, PT_GNU_STACK size is significant on uclinux
6193*ef5ccd6cSJohn Marino systems. */
61945796c8dcSSimon Schubert map->p_size = segment->p_memsz;
61955796c8dcSSimon Schubert map->p_size_valid = 1;
61965796c8dcSSimon Schubert }
61975796c8dcSSimon Schubert
61985796c8dcSSimon Schubert /* Determine if this segment contains the ELF file header
61995796c8dcSSimon Schubert and if it contains the program headers themselves. */
62005796c8dcSSimon Schubert map->includes_filehdr = (segment->p_offset == 0
62015796c8dcSSimon Schubert && segment->p_filesz >= iehdr->e_ehsize);
62025796c8dcSSimon Schubert
62035796c8dcSSimon Schubert map->includes_phdrs = 0;
62045796c8dcSSimon Schubert if (! phdr_included || segment->p_type != PT_LOAD)
62055796c8dcSSimon Schubert {
62065796c8dcSSimon Schubert map->includes_phdrs =
62075796c8dcSSimon Schubert (segment->p_offset <= (bfd_vma) iehdr->e_phoff
62085796c8dcSSimon Schubert && (segment->p_offset + segment->p_filesz
62095796c8dcSSimon Schubert >= ((bfd_vma) iehdr->e_phoff
62105796c8dcSSimon Schubert + iehdr->e_phnum * iehdr->e_phentsize)));
62115796c8dcSSimon Schubert
62125796c8dcSSimon Schubert if (segment->p_type == PT_LOAD && map->includes_phdrs)
62135796c8dcSSimon Schubert phdr_included = TRUE;
62145796c8dcSSimon Schubert }
62155796c8dcSSimon Schubert
6216c50c785cSJohn Marino lowest_section = first_section;
62175796c8dcSSimon Schubert if (section_count != 0)
62185796c8dcSSimon Schubert {
62195796c8dcSSimon Schubert unsigned int isec = 0;
62205796c8dcSSimon Schubert
62215796c8dcSSimon Schubert for (section = first_section;
62225796c8dcSSimon Schubert section != NULL;
62235796c8dcSSimon Schubert section = section->next)
62245796c8dcSSimon Schubert {
62255796c8dcSSimon Schubert this_hdr = &(elf_section_data(section)->this_hdr);
6226c50c785cSJohn Marino if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
62275796c8dcSSimon Schubert {
62285796c8dcSSimon Schubert map->sections[isec++] = section->output_section;
6229c50c785cSJohn Marino if (section->lma < lowest_section->lma)
6230c50c785cSJohn Marino lowest_section = section;
6231c50c785cSJohn Marino if ((section->flags & SEC_ALLOC) != 0)
6232c50c785cSJohn Marino {
6233c50c785cSJohn Marino bfd_vma seg_off;
6234c50c785cSJohn Marino
6235c50c785cSJohn Marino /* Section lmas are set up from PT_LOAD header
6236c50c785cSJohn Marino p_paddr in _bfd_elf_make_section_from_shdr.
6237c50c785cSJohn Marino If this header has a p_paddr that disagrees
6238c50c785cSJohn Marino with the section lma, flag the p_paddr as
6239c50c785cSJohn Marino invalid. */
6240c50c785cSJohn Marino if ((section->flags & SEC_LOAD) != 0)
6241c50c785cSJohn Marino seg_off = this_hdr->sh_offset - segment->p_offset;
6242c50c785cSJohn Marino else
6243c50c785cSJohn Marino seg_off = this_hdr->sh_addr - segment->p_vaddr;
6244c50c785cSJohn Marino if (section->lma - segment->p_paddr != seg_off)
6245c50c785cSJohn Marino map->p_paddr_valid = FALSE;
6246c50c785cSJohn Marino }
62475796c8dcSSimon Schubert if (isec == section_count)
62485796c8dcSSimon Schubert break;
62495796c8dcSSimon Schubert }
62505796c8dcSSimon Schubert }
62515796c8dcSSimon Schubert }
62525796c8dcSSimon Schubert
6253c50c785cSJohn Marino if (map->includes_filehdr && lowest_section != NULL)
6254c50c785cSJohn Marino /* We need to keep the space used by the headers fixed. */
6255c50c785cSJohn Marino map->header_size = lowest_section->vma - segment->p_vaddr;
6256c50c785cSJohn Marino
6257c50c785cSJohn Marino if (!map->includes_phdrs
6258c50c785cSJohn Marino && !map->includes_filehdr
6259c50c785cSJohn Marino && map->p_paddr_valid)
6260c50c785cSJohn Marino /* There is some other padding before the first section. */
6261c50c785cSJohn Marino map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
6262c50c785cSJohn Marino - segment->p_paddr);
6263c50c785cSJohn Marino
62645796c8dcSSimon Schubert map->count = section_count;
62655796c8dcSSimon Schubert *pointer_to_map = map;
62665796c8dcSSimon Schubert pointer_to_map = &map->next;
62675796c8dcSSimon Schubert }
62685796c8dcSSimon Schubert
6269*ef5ccd6cSJohn Marino elf_seg_map (obfd) = map_first;
62705796c8dcSSimon Schubert return TRUE;
62715796c8dcSSimon Schubert }
62725796c8dcSSimon Schubert
62735796c8dcSSimon Schubert /* Copy private BFD data. This copies or rewrites ELF program header
62745796c8dcSSimon Schubert information. */
62755796c8dcSSimon Schubert
62765796c8dcSSimon Schubert static bfd_boolean
copy_private_bfd_data(bfd * ibfd,bfd * obfd)62775796c8dcSSimon Schubert copy_private_bfd_data (bfd *ibfd, bfd *obfd)
62785796c8dcSSimon Schubert {
62795796c8dcSSimon Schubert if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
62805796c8dcSSimon Schubert || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
62815796c8dcSSimon Schubert return TRUE;
62825796c8dcSSimon Schubert
62835796c8dcSSimon Schubert if (elf_tdata (ibfd)->phdr == NULL)
62845796c8dcSSimon Schubert return TRUE;
62855796c8dcSSimon Schubert
62865796c8dcSSimon Schubert if (ibfd->xvec == obfd->xvec)
62875796c8dcSSimon Schubert {
62885796c8dcSSimon Schubert /* Check to see if any sections in the input BFD
62895796c8dcSSimon Schubert covered by ELF program header have changed. */
62905796c8dcSSimon Schubert Elf_Internal_Phdr *segment;
62915796c8dcSSimon Schubert asection *section, *osec;
62925796c8dcSSimon Schubert unsigned int i, num_segments;
62935796c8dcSSimon Schubert Elf_Internal_Shdr *this_hdr;
62945796c8dcSSimon Schubert const struct elf_backend_data *bed;
62955796c8dcSSimon Schubert
62965796c8dcSSimon Schubert bed = get_elf_backend_data (ibfd);
62975796c8dcSSimon Schubert
62985796c8dcSSimon Schubert /* Regenerate the segment map if p_paddr is set to 0. */
62995796c8dcSSimon Schubert if (bed->want_p_paddr_set_to_zero)
63005796c8dcSSimon Schubert goto rewrite;
63015796c8dcSSimon Schubert
63025796c8dcSSimon Schubert /* Initialize the segment mark field. */
63035796c8dcSSimon Schubert for (section = obfd->sections; section != NULL;
63045796c8dcSSimon Schubert section = section->next)
63055796c8dcSSimon Schubert section->segment_mark = FALSE;
63065796c8dcSSimon Schubert
63075796c8dcSSimon Schubert num_segments = elf_elfheader (ibfd)->e_phnum;
63085796c8dcSSimon Schubert for (i = 0, segment = elf_tdata (ibfd)->phdr;
63095796c8dcSSimon Schubert i < num_segments;
63105796c8dcSSimon Schubert i++, segment++)
63115796c8dcSSimon Schubert {
63125796c8dcSSimon Schubert /* PR binutils/3535. The Solaris linker always sets the p_paddr
63135796c8dcSSimon Schubert and p_memsz fields of special segments (DYNAMIC, INTERP) to 0
63145796c8dcSSimon Schubert which severly confuses things, so always regenerate the segment
63155796c8dcSSimon Schubert map in this case. */
63165796c8dcSSimon Schubert if (segment->p_paddr == 0
63175796c8dcSSimon Schubert && segment->p_memsz == 0
63185796c8dcSSimon Schubert && (segment->p_type == PT_INTERP || segment->p_type == PT_DYNAMIC))
63195796c8dcSSimon Schubert goto rewrite;
63205796c8dcSSimon Schubert
63215796c8dcSSimon Schubert for (section = ibfd->sections;
63225796c8dcSSimon Schubert section != NULL; section = section->next)
63235796c8dcSSimon Schubert {
63245796c8dcSSimon Schubert /* We mark the output section so that we know it comes
63255796c8dcSSimon Schubert from the input BFD. */
63265796c8dcSSimon Schubert osec = section->output_section;
63275796c8dcSSimon Schubert if (osec)
63285796c8dcSSimon Schubert osec->segment_mark = TRUE;
63295796c8dcSSimon Schubert
63305796c8dcSSimon Schubert /* Check if this section is covered by the segment. */
63315796c8dcSSimon Schubert this_hdr = &(elf_section_data(section)->this_hdr);
6332c50c785cSJohn Marino if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
63335796c8dcSSimon Schubert {
63345796c8dcSSimon Schubert /* FIXME: Check if its output section is changed or
63355796c8dcSSimon Schubert removed. What else do we need to check? */
63365796c8dcSSimon Schubert if (osec == NULL
63375796c8dcSSimon Schubert || section->flags != osec->flags
63385796c8dcSSimon Schubert || section->lma != osec->lma
63395796c8dcSSimon Schubert || section->vma != osec->vma
63405796c8dcSSimon Schubert || section->size != osec->size
63415796c8dcSSimon Schubert || section->rawsize != osec->rawsize
63425796c8dcSSimon Schubert || section->alignment_power != osec->alignment_power)
63435796c8dcSSimon Schubert goto rewrite;
63445796c8dcSSimon Schubert }
63455796c8dcSSimon Schubert }
63465796c8dcSSimon Schubert }
63475796c8dcSSimon Schubert
63485796c8dcSSimon Schubert /* Check to see if any output section do not come from the
63495796c8dcSSimon Schubert input BFD. */
63505796c8dcSSimon Schubert for (section = obfd->sections; section != NULL;
63515796c8dcSSimon Schubert section = section->next)
63525796c8dcSSimon Schubert {
63535796c8dcSSimon Schubert if (section->segment_mark == FALSE)
63545796c8dcSSimon Schubert goto rewrite;
63555796c8dcSSimon Schubert else
63565796c8dcSSimon Schubert section->segment_mark = FALSE;
63575796c8dcSSimon Schubert }
63585796c8dcSSimon Schubert
63595796c8dcSSimon Schubert return copy_elf_program_header (ibfd, obfd);
63605796c8dcSSimon Schubert }
63615796c8dcSSimon Schubert
63625796c8dcSSimon Schubert rewrite:
6363*ef5ccd6cSJohn Marino if (ibfd->xvec == obfd->xvec)
6364*ef5ccd6cSJohn Marino {
6365*ef5ccd6cSJohn Marino /* When rewriting program header, set the output maxpagesize to
6366*ef5ccd6cSJohn Marino the maximum alignment of input PT_LOAD segments. */
6367*ef5ccd6cSJohn Marino Elf_Internal_Phdr *segment;
6368*ef5ccd6cSJohn Marino unsigned int i;
6369*ef5ccd6cSJohn Marino unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;
6370*ef5ccd6cSJohn Marino bfd_vma maxpagesize = 0;
6371*ef5ccd6cSJohn Marino
6372*ef5ccd6cSJohn Marino for (i = 0, segment = elf_tdata (ibfd)->phdr;
6373*ef5ccd6cSJohn Marino i < num_segments;
6374*ef5ccd6cSJohn Marino i++, segment++)
6375*ef5ccd6cSJohn Marino if (segment->p_type == PT_LOAD
6376*ef5ccd6cSJohn Marino && maxpagesize < segment->p_align)
6377*ef5ccd6cSJohn Marino maxpagesize = segment->p_align;
6378*ef5ccd6cSJohn Marino
6379*ef5ccd6cSJohn Marino if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
6380*ef5ccd6cSJohn Marino bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
6381*ef5ccd6cSJohn Marino }
6382*ef5ccd6cSJohn Marino
63835796c8dcSSimon Schubert return rewrite_elf_program_header (ibfd, obfd);
63845796c8dcSSimon Schubert }
63855796c8dcSSimon Schubert
63865796c8dcSSimon Schubert /* Initialize private output section information from input section. */
63875796c8dcSSimon Schubert
63885796c8dcSSimon Schubert bfd_boolean
_bfd_elf_init_private_section_data(bfd * ibfd,asection * isec,bfd * obfd,asection * osec,struct bfd_link_info * link_info)63895796c8dcSSimon Schubert _bfd_elf_init_private_section_data (bfd *ibfd,
63905796c8dcSSimon Schubert asection *isec,
63915796c8dcSSimon Schubert bfd *obfd,
63925796c8dcSSimon Schubert asection *osec,
63935796c8dcSSimon Schubert struct bfd_link_info *link_info)
63945796c8dcSSimon Schubert
63955796c8dcSSimon Schubert {
63965796c8dcSSimon Schubert Elf_Internal_Shdr *ihdr, *ohdr;
6397cf7f2e2dSJohn Marino bfd_boolean final_link = link_info != NULL && !link_info->relocatable;
63985796c8dcSSimon Schubert
63995796c8dcSSimon Schubert if (ibfd->xvec->flavour != bfd_target_elf_flavour
64005796c8dcSSimon Schubert || obfd->xvec->flavour != bfd_target_elf_flavour)
64015796c8dcSSimon Schubert return TRUE;
64025796c8dcSSimon Schubert
6403a45ae5f8SJohn Marino BFD_ASSERT (elf_section_data (osec) != NULL);
6404a45ae5f8SJohn Marino
6405cf7f2e2dSJohn Marino /* For objcopy and relocatable link, don't copy the output ELF
6406cf7f2e2dSJohn Marino section type from input if the output BFD section flags have been
6407cf7f2e2dSJohn Marino set to something different. For a final link allow some flags
6408cf7f2e2dSJohn Marino that the linker clears to differ. */
64095796c8dcSSimon Schubert if (elf_section_type (osec) == SHT_NULL
6410cf7f2e2dSJohn Marino && (osec->flags == isec->flags
6411cf7f2e2dSJohn Marino || (final_link
6412cf7f2e2dSJohn Marino && ((osec->flags ^ isec->flags)
6413c50c785cSJohn Marino & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
64145796c8dcSSimon Schubert elf_section_type (osec) = elf_section_type (isec);
64155796c8dcSSimon Schubert
64165796c8dcSSimon Schubert /* FIXME: Is this correct for all OS/PROC specific flags? */
64175796c8dcSSimon Schubert elf_section_flags (osec) |= (elf_section_flags (isec)
64185796c8dcSSimon Schubert & (SHF_MASKOS | SHF_MASKPROC));
64195796c8dcSSimon Schubert
64205796c8dcSSimon Schubert /* Set things up for objcopy and relocatable link. The output
64215796c8dcSSimon Schubert SHT_GROUP section will have its elf_next_in_group pointing back
64225796c8dcSSimon Schubert to the input group members. Ignore linker created group section.
64235796c8dcSSimon Schubert See elfNN_ia64_object_p in elfxx-ia64.c. */
6424cf7f2e2dSJohn Marino if (!final_link)
64255796c8dcSSimon Schubert {
64265796c8dcSSimon Schubert if (elf_sec_group (isec) == NULL
64275796c8dcSSimon Schubert || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
64285796c8dcSSimon Schubert {
64295796c8dcSSimon Schubert if (elf_section_flags (isec) & SHF_GROUP)
64305796c8dcSSimon Schubert elf_section_flags (osec) |= SHF_GROUP;
64315796c8dcSSimon Schubert elf_next_in_group (osec) = elf_next_in_group (isec);
64325796c8dcSSimon Schubert elf_section_data (osec)->group = elf_section_data (isec)->group;
64335796c8dcSSimon Schubert }
64345796c8dcSSimon Schubert }
64355796c8dcSSimon Schubert
64365796c8dcSSimon Schubert ihdr = &elf_section_data (isec)->this_hdr;
64375796c8dcSSimon Schubert
64385796c8dcSSimon Schubert /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
64395796c8dcSSimon Schubert don't use the output section of the linked-to section since it
64405796c8dcSSimon Schubert may be NULL at this point. */
64415796c8dcSSimon Schubert if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
64425796c8dcSSimon Schubert {
64435796c8dcSSimon Schubert ohdr = &elf_section_data (osec)->this_hdr;
64445796c8dcSSimon Schubert ohdr->sh_flags |= SHF_LINK_ORDER;
64455796c8dcSSimon Schubert elf_linked_to_section (osec) = elf_linked_to_section (isec);
64465796c8dcSSimon Schubert }
64475796c8dcSSimon Schubert
64485796c8dcSSimon Schubert osec->use_rela_p = isec->use_rela_p;
64495796c8dcSSimon Schubert
64505796c8dcSSimon Schubert return TRUE;
64515796c8dcSSimon Schubert }
64525796c8dcSSimon Schubert
64535796c8dcSSimon Schubert /* Copy private section information. This copies over the entsize
64545796c8dcSSimon Schubert field, and sometimes the info field. */
64555796c8dcSSimon Schubert
64565796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_section_data(bfd * ibfd,asection * isec,bfd * obfd,asection * osec)64575796c8dcSSimon Schubert _bfd_elf_copy_private_section_data (bfd *ibfd,
64585796c8dcSSimon Schubert asection *isec,
64595796c8dcSSimon Schubert bfd *obfd,
64605796c8dcSSimon Schubert asection *osec)
64615796c8dcSSimon Schubert {
64625796c8dcSSimon Schubert Elf_Internal_Shdr *ihdr, *ohdr;
64635796c8dcSSimon Schubert
64645796c8dcSSimon Schubert if (ibfd->xvec->flavour != bfd_target_elf_flavour
64655796c8dcSSimon Schubert || obfd->xvec->flavour != bfd_target_elf_flavour)
64665796c8dcSSimon Schubert return TRUE;
64675796c8dcSSimon Schubert
64685796c8dcSSimon Schubert ihdr = &elf_section_data (isec)->this_hdr;
64695796c8dcSSimon Schubert ohdr = &elf_section_data (osec)->this_hdr;
64705796c8dcSSimon Schubert
64715796c8dcSSimon Schubert ohdr->sh_entsize = ihdr->sh_entsize;
64725796c8dcSSimon Schubert
64735796c8dcSSimon Schubert if (ihdr->sh_type == SHT_SYMTAB
64745796c8dcSSimon Schubert || ihdr->sh_type == SHT_DYNSYM
64755796c8dcSSimon Schubert || ihdr->sh_type == SHT_GNU_verneed
64765796c8dcSSimon Schubert || ihdr->sh_type == SHT_GNU_verdef)
64775796c8dcSSimon Schubert ohdr->sh_info = ihdr->sh_info;
64785796c8dcSSimon Schubert
64795796c8dcSSimon Schubert return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
64805796c8dcSSimon Schubert NULL);
64815796c8dcSSimon Schubert }
64825796c8dcSSimon Schubert
6483cf7f2e2dSJohn Marino /* Look at all the SHT_GROUP sections in IBFD, making any adjustments
6484cf7f2e2dSJohn Marino necessary if we are removing either the SHT_GROUP section or any of
6485cf7f2e2dSJohn Marino the group member sections. DISCARDED is the value that a section's
6486cf7f2e2dSJohn Marino output_section has if the section will be discarded, NULL when this
6487cf7f2e2dSJohn Marino function is called from objcopy, bfd_abs_section_ptr when called
6488cf7f2e2dSJohn Marino from the linker. */
6489cf7f2e2dSJohn Marino
6490cf7f2e2dSJohn Marino bfd_boolean
_bfd_elf_fixup_group_sections(bfd * ibfd,asection * discarded)6491cf7f2e2dSJohn Marino _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
6492cf7f2e2dSJohn Marino {
6493cf7f2e2dSJohn Marino asection *isec;
6494cf7f2e2dSJohn Marino
6495cf7f2e2dSJohn Marino for (isec = ibfd->sections; isec != NULL; isec = isec->next)
6496cf7f2e2dSJohn Marino if (elf_section_type (isec) == SHT_GROUP)
6497cf7f2e2dSJohn Marino {
6498cf7f2e2dSJohn Marino asection *first = elf_next_in_group (isec);
6499cf7f2e2dSJohn Marino asection *s = first;
6500cf7f2e2dSJohn Marino bfd_size_type removed = 0;
6501cf7f2e2dSJohn Marino
6502cf7f2e2dSJohn Marino while (s != NULL)
6503cf7f2e2dSJohn Marino {
6504cf7f2e2dSJohn Marino /* If this member section is being output but the
6505cf7f2e2dSJohn Marino SHT_GROUP section is not, then clear the group info
6506cf7f2e2dSJohn Marino set up by _bfd_elf_copy_private_section_data. */
6507cf7f2e2dSJohn Marino if (s->output_section != discarded
6508cf7f2e2dSJohn Marino && isec->output_section == discarded)
6509cf7f2e2dSJohn Marino {
6510cf7f2e2dSJohn Marino elf_section_flags (s->output_section) &= ~SHF_GROUP;
6511cf7f2e2dSJohn Marino elf_group_name (s->output_section) = NULL;
6512cf7f2e2dSJohn Marino }
6513cf7f2e2dSJohn Marino /* Conversely, if the member section is not being output
6514cf7f2e2dSJohn Marino but the SHT_GROUP section is, then adjust its size. */
6515cf7f2e2dSJohn Marino else if (s->output_section == discarded
6516cf7f2e2dSJohn Marino && isec->output_section != discarded)
6517cf7f2e2dSJohn Marino removed += 4;
6518cf7f2e2dSJohn Marino s = elf_next_in_group (s);
6519cf7f2e2dSJohn Marino if (s == first)
6520cf7f2e2dSJohn Marino break;
6521cf7f2e2dSJohn Marino }
6522cf7f2e2dSJohn Marino if (removed != 0)
6523cf7f2e2dSJohn Marino {
6524cf7f2e2dSJohn Marino if (discarded != NULL)
6525cf7f2e2dSJohn Marino {
6526cf7f2e2dSJohn Marino /* If we've been called for ld -r, then we need to
6527cf7f2e2dSJohn Marino adjust the input section size. This function may
6528cf7f2e2dSJohn Marino be called multiple times, so save the original
6529cf7f2e2dSJohn Marino size. */
6530cf7f2e2dSJohn Marino if (isec->rawsize == 0)
6531cf7f2e2dSJohn Marino isec->rawsize = isec->size;
6532cf7f2e2dSJohn Marino isec->size = isec->rawsize - removed;
6533cf7f2e2dSJohn Marino }
6534cf7f2e2dSJohn Marino else
6535cf7f2e2dSJohn Marino {
6536cf7f2e2dSJohn Marino /* Adjust the output section size when called from
6537cf7f2e2dSJohn Marino objcopy. */
6538cf7f2e2dSJohn Marino isec->output_section->size -= removed;
6539cf7f2e2dSJohn Marino }
6540cf7f2e2dSJohn Marino }
6541cf7f2e2dSJohn Marino }
6542cf7f2e2dSJohn Marino
6543cf7f2e2dSJohn Marino return TRUE;
6544cf7f2e2dSJohn Marino }
6545cf7f2e2dSJohn Marino
65465796c8dcSSimon Schubert /* Copy private header information. */
65475796c8dcSSimon Schubert
65485796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_header_data(bfd * ibfd,bfd * obfd)65495796c8dcSSimon Schubert _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
65505796c8dcSSimon Schubert {
65515796c8dcSSimon Schubert if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
65525796c8dcSSimon Schubert || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
65535796c8dcSSimon Schubert return TRUE;
65545796c8dcSSimon Schubert
65555796c8dcSSimon Schubert /* Copy over private BFD data if it has not already been copied.
65565796c8dcSSimon Schubert This must be done here, rather than in the copy_private_bfd_data
65575796c8dcSSimon Schubert entry point, because the latter is called after the section
65585796c8dcSSimon Schubert contents have been set, which means that the program headers have
65595796c8dcSSimon Schubert already been worked out. */
6560*ef5ccd6cSJohn Marino if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL)
65615796c8dcSSimon Schubert {
65625796c8dcSSimon Schubert if (! copy_private_bfd_data (ibfd, obfd))
65635796c8dcSSimon Schubert return FALSE;
65645796c8dcSSimon Schubert }
65655796c8dcSSimon Schubert
6566cf7f2e2dSJohn Marino return _bfd_elf_fixup_group_sections (ibfd, NULL);
65675796c8dcSSimon Schubert }
65685796c8dcSSimon Schubert
65695796c8dcSSimon Schubert /* Copy private symbol information. If this symbol is in a section
65705796c8dcSSimon Schubert which we did not map into a BFD section, try to map the section
65715796c8dcSSimon Schubert index correctly. We use special macro definitions for the mapped
65725796c8dcSSimon Schubert section indices; these definitions are interpreted by the
65735796c8dcSSimon Schubert swap_out_syms function. */
65745796c8dcSSimon Schubert
65755796c8dcSSimon Schubert #define MAP_ONESYMTAB (SHN_HIOS + 1)
65765796c8dcSSimon Schubert #define MAP_DYNSYMTAB (SHN_HIOS + 2)
65775796c8dcSSimon Schubert #define MAP_STRTAB (SHN_HIOS + 3)
65785796c8dcSSimon Schubert #define MAP_SHSTRTAB (SHN_HIOS + 4)
65795796c8dcSSimon Schubert #define MAP_SYM_SHNDX (SHN_HIOS + 5)
65805796c8dcSSimon Schubert
65815796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_symbol_data(bfd * ibfd,asymbol * isymarg,bfd * obfd,asymbol * osymarg)65825796c8dcSSimon Schubert _bfd_elf_copy_private_symbol_data (bfd *ibfd,
65835796c8dcSSimon Schubert asymbol *isymarg,
65845796c8dcSSimon Schubert bfd *obfd,
65855796c8dcSSimon Schubert asymbol *osymarg)
65865796c8dcSSimon Schubert {
65875796c8dcSSimon Schubert elf_symbol_type *isym, *osym;
65885796c8dcSSimon Schubert
65895796c8dcSSimon Schubert if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
65905796c8dcSSimon Schubert || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
65915796c8dcSSimon Schubert return TRUE;
65925796c8dcSSimon Schubert
65935796c8dcSSimon Schubert isym = elf_symbol_from (ibfd, isymarg);
65945796c8dcSSimon Schubert osym = elf_symbol_from (obfd, osymarg);
65955796c8dcSSimon Schubert
65965796c8dcSSimon Schubert if (isym != NULL
65975796c8dcSSimon Schubert && isym->internal_elf_sym.st_shndx != 0
65985796c8dcSSimon Schubert && osym != NULL
65995796c8dcSSimon Schubert && bfd_is_abs_section (isym->symbol.section))
66005796c8dcSSimon Schubert {
66015796c8dcSSimon Schubert unsigned int shndx;
66025796c8dcSSimon Schubert
66035796c8dcSSimon Schubert shndx = isym->internal_elf_sym.st_shndx;
66045796c8dcSSimon Schubert if (shndx == elf_onesymtab (ibfd))
66055796c8dcSSimon Schubert shndx = MAP_ONESYMTAB;
66065796c8dcSSimon Schubert else if (shndx == elf_dynsymtab (ibfd))
66075796c8dcSSimon Schubert shndx = MAP_DYNSYMTAB;
6608*ef5ccd6cSJohn Marino else if (shndx == elf_strtab_sec (ibfd))
66095796c8dcSSimon Schubert shndx = MAP_STRTAB;
6610*ef5ccd6cSJohn Marino else if (shndx == elf_shstrtab_sec (ibfd))
66115796c8dcSSimon Schubert shndx = MAP_SHSTRTAB;
6612*ef5ccd6cSJohn Marino else if (shndx == elf_symtab_shndx (ibfd))
66135796c8dcSSimon Schubert shndx = MAP_SYM_SHNDX;
66145796c8dcSSimon Schubert osym->internal_elf_sym.st_shndx = shndx;
66155796c8dcSSimon Schubert }
66165796c8dcSSimon Schubert
66175796c8dcSSimon Schubert return TRUE;
66185796c8dcSSimon Schubert }
66195796c8dcSSimon Schubert
66205796c8dcSSimon Schubert /* Swap out the symbols. */
66215796c8dcSSimon Schubert
66225796c8dcSSimon Schubert static bfd_boolean
swap_out_syms(bfd * abfd,struct bfd_strtab_hash ** sttp,int relocatable_p)66235796c8dcSSimon Schubert swap_out_syms (bfd *abfd,
66245796c8dcSSimon Schubert struct bfd_strtab_hash **sttp,
66255796c8dcSSimon Schubert int relocatable_p)
66265796c8dcSSimon Schubert {
66275796c8dcSSimon Schubert const struct elf_backend_data *bed;
66285796c8dcSSimon Schubert int symcount;
66295796c8dcSSimon Schubert asymbol **syms;
66305796c8dcSSimon Schubert struct bfd_strtab_hash *stt;
66315796c8dcSSimon Schubert Elf_Internal_Shdr *symtab_hdr;
66325796c8dcSSimon Schubert Elf_Internal_Shdr *symtab_shndx_hdr;
66335796c8dcSSimon Schubert Elf_Internal_Shdr *symstrtab_hdr;
66345796c8dcSSimon Schubert bfd_byte *outbound_syms;
66355796c8dcSSimon Schubert bfd_byte *outbound_shndx;
66365796c8dcSSimon Schubert int idx;
6637*ef5ccd6cSJohn Marino unsigned int num_locals;
66385796c8dcSSimon Schubert bfd_size_type amt;
66395796c8dcSSimon Schubert bfd_boolean name_local_sections;
66405796c8dcSSimon Schubert
6641*ef5ccd6cSJohn Marino if (!elf_map_symbols (abfd, &num_locals))
66425796c8dcSSimon Schubert return FALSE;
66435796c8dcSSimon Schubert
66445796c8dcSSimon Schubert /* Dump out the symtabs. */
66455796c8dcSSimon Schubert stt = _bfd_elf_stringtab_init ();
66465796c8dcSSimon Schubert if (stt == NULL)
66475796c8dcSSimon Schubert return FALSE;
66485796c8dcSSimon Schubert
66495796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
66505796c8dcSSimon Schubert symcount = bfd_get_symcount (abfd);
66515796c8dcSSimon Schubert symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
66525796c8dcSSimon Schubert symtab_hdr->sh_type = SHT_SYMTAB;
66535796c8dcSSimon Schubert symtab_hdr->sh_entsize = bed->s->sizeof_sym;
66545796c8dcSSimon Schubert symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
6655*ef5ccd6cSJohn Marino symtab_hdr->sh_info = num_locals + 1;
66565796c8dcSSimon Schubert symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
66575796c8dcSSimon Schubert
66585796c8dcSSimon Schubert symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
66595796c8dcSSimon Schubert symstrtab_hdr->sh_type = SHT_STRTAB;
66605796c8dcSSimon Schubert
66615796c8dcSSimon Schubert outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount,
66625796c8dcSSimon Schubert bed->s->sizeof_sym);
66635796c8dcSSimon Schubert if (outbound_syms == NULL)
66645796c8dcSSimon Schubert {
66655796c8dcSSimon Schubert _bfd_stringtab_free (stt);
66665796c8dcSSimon Schubert return FALSE;
66675796c8dcSSimon Schubert }
66685796c8dcSSimon Schubert symtab_hdr->contents = outbound_syms;
66695796c8dcSSimon Schubert
66705796c8dcSSimon Schubert outbound_shndx = NULL;
66715796c8dcSSimon Schubert symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
66725796c8dcSSimon Schubert if (symtab_shndx_hdr->sh_name != 0)
66735796c8dcSSimon Schubert {
66745796c8dcSSimon Schubert amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
66755796c8dcSSimon Schubert outbound_shndx = (bfd_byte *)
66765796c8dcSSimon Schubert bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
66775796c8dcSSimon Schubert if (outbound_shndx == NULL)
66785796c8dcSSimon Schubert {
66795796c8dcSSimon Schubert _bfd_stringtab_free (stt);
66805796c8dcSSimon Schubert return FALSE;
66815796c8dcSSimon Schubert }
66825796c8dcSSimon Schubert
66835796c8dcSSimon Schubert symtab_shndx_hdr->contents = outbound_shndx;
66845796c8dcSSimon Schubert symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
66855796c8dcSSimon Schubert symtab_shndx_hdr->sh_size = amt;
66865796c8dcSSimon Schubert symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
66875796c8dcSSimon Schubert symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
66885796c8dcSSimon Schubert }
66895796c8dcSSimon Schubert
66905796c8dcSSimon Schubert /* Now generate the data (for "contents"). */
66915796c8dcSSimon Schubert {
66925796c8dcSSimon Schubert /* Fill in zeroth symbol and swap it out. */
66935796c8dcSSimon Schubert Elf_Internal_Sym sym;
66945796c8dcSSimon Schubert sym.st_name = 0;
66955796c8dcSSimon Schubert sym.st_value = 0;
66965796c8dcSSimon Schubert sym.st_size = 0;
66975796c8dcSSimon Schubert sym.st_info = 0;
66985796c8dcSSimon Schubert sym.st_other = 0;
66995796c8dcSSimon Schubert sym.st_shndx = SHN_UNDEF;
6700c50c785cSJohn Marino sym.st_target_internal = 0;
67015796c8dcSSimon Schubert bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
67025796c8dcSSimon Schubert outbound_syms += bed->s->sizeof_sym;
67035796c8dcSSimon Schubert if (outbound_shndx != NULL)
67045796c8dcSSimon Schubert outbound_shndx += sizeof (Elf_External_Sym_Shndx);
67055796c8dcSSimon Schubert }
67065796c8dcSSimon Schubert
67075796c8dcSSimon Schubert name_local_sections
67085796c8dcSSimon Schubert = (bed->elf_backend_name_local_section_symbols
67095796c8dcSSimon Schubert && bed->elf_backend_name_local_section_symbols (abfd));
67105796c8dcSSimon Schubert
67115796c8dcSSimon Schubert syms = bfd_get_outsymbols (abfd);
67125796c8dcSSimon Schubert for (idx = 0; idx < symcount; idx++)
67135796c8dcSSimon Schubert {
67145796c8dcSSimon Schubert Elf_Internal_Sym sym;
67155796c8dcSSimon Schubert bfd_vma value = syms[idx]->value;
67165796c8dcSSimon Schubert elf_symbol_type *type_ptr;
67175796c8dcSSimon Schubert flagword flags = syms[idx]->flags;
67185796c8dcSSimon Schubert int type;
67195796c8dcSSimon Schubert
67205796c8dcSSimon Schubert if (!name_local_sections
67215796c8dcSSimon Schubert && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
67225796c8dcSSimon Schubert {
67235796c8dcSSimon Schubert /* Local section symbols have no name. */
67245796c8dcSSimon Schubert sym.st_name = 0;
67255796c8dcSSimon Schubert }
67265796c8dcSSimon Schubert else
67275796c8dcSSimon Schubert {
67285796c8dcSSimon Schubert sym.st_name = (unsigned long) _bfd_stringtab_add (stt,
67295796c8dcSSimon Schubert syms[idx]->name,
67305796c8dcSSimon Schubert TRUE, FALSE);
67315796c8dcSSimon Schubert if (sym.st_name == (unsigned long) -1)
67325796c8dcSSimon Schubert {
67335796c8dcSSimon Schubert _bfd_stringtab_free (stt);
67345796c8dcSSimon Schubert return FALSE;
67355796c8dcSSimon Schubert }
67365796c8dcSSimon Schubert }
67375796c8dcSSimon Schubert
67385796c8dcSSimon Schubert type_ptr = elf_symbol_from (abfd, syms[idx]);
67395796c8dcSSimon Schubert
67405796c8dcSSimon Schubert if ((flags & BSF_SECTION_SYM) == 0
67415796c8dcSSimon Schubert && bfd_is_com_section (syms[idx]->section))
67425796c8dcSSimon Schubert {
67435796c8dcSSimon Schubert /* ELF common symbols put the alignment into the `value' field,
67445796c8dcSSimon Schubert and the size into the `size' field. This is backwards from
67455796c8dcSSimon Schubert how BFD handles it, so reverse it here. */
67465796c8dcSSimon Schubert sym.st_size = value;
67475796c8dcSSimon Schubert if (type_ptr == NULL
67485796c8dcSSimon Schubert || type_ptr->internal_elf_sym.st_value == 0)
67495796c8dcSSimon Schubert sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
67505796c8dcSSimon Schubert else
67515796c8dcSSimon Schubert sym.st_value = type_ptr->internal_elf_sym.st_value;
67525796c8dcSSimon Schubert sym.st_shndx = _bfd_elf_section_from_bfd_section
67535796c8dcSSimon Schubert (abfd, syms[idx]->section);
67545796c8dcSSimon Schubert }
67555796c8dcSSimon Schubert else
67565796c8dcSSimon Schubert {
67575796c8dcSSimon Schubert asection *sec = syms[idx]->section;
67585796c8dcSSimon Schubert unsigned int shndx;
67595796c8dcSSimon Schubert
67605796c8dcSSimon Schubert if (sec->output_section)
67615796c8dcSSimon Schubert {
67625796c8dcSSimon Schubert value += sec->output_offset;
67635796c8dcSSimon Schubert sec = sec->output_section;
67645796c8dcSSimon Schubert }
67655796c8dcSSimon Schubert
67665796c8dcSSimon Schubert /* Don't add in the section vma for relocatable output. */
67675796c8dcSSimon Schubert if (! relocatable_p)
67685796c8dcSSimon Schubert value += sec->vma;
67695796c8dcSSimon Schubert sym.st_value = value;
67705796c8dcSSimon Schubert sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;
67715796c8dcSSimon Schubert
67725796c8dcSSimon Schubert if (bfd_is_abs_section (sec)
67735796c8dcSSimon Schubert && type_ptr != NULL
67745796c8dcSSimon Schubert && type_ptr->internal_elf_sym.st_shndx != 0)
67755796c8dcSSimon Schubert {
67765796c8dcSSimon Schubert /* This symbol is in a real ELF section which we did
67775796c8dcSSimon Schubert not create as a BFD section. Undo the mapping done
67785796c8dcSSimon Schubert by copy_private_symbol_data. */
67795796c8dcSSimon Schubert shndx = type_ptr->internal_elf_sym.st_shndx;
67805796c8dcSSimon Schubert switch (shndx)
67815796c8dcSSimon Schubert {
67825796c8dcSSimon Schubert case MAP_ONESYMTAB:
67835796c8dcSSimon Schubert shndx = elf_onesymtab (abfd);
67845796c8dcSSimon Schubert break;
67855796c8dcSSimon Schubert case MAP_DYNSYMTAB:
67865796c8dcSSimon Schubert shndx = elf_dynsymtab (abfd);
67875796c8dcSSimon Schubert break;
67885796c8dcSSimon Schubert case MAP_STRTAB:
6789*ef5ccd6cSJohn Marino shndx = elf_strtab_sec (abfd);
67905796c8dcSSimon Schubert break;
67915796c8dcSSimon Schubert case MAP_SHSTRTAB:
6792*ef5ccd6cSJohn Marino shndx = elf_shstrtab_sec (abfd);
67935796c8dcSSimon Schubert break;
67945796c8dcSSimon Schubert case MAP_SYM_SHNDX:
6795*ef5ccd6cSJohn Marino shndx = elf_symtab_shndx (abfd);
67965796c8dcSSimon Schubert break;
67975796c8dcSSimon Schubert default:
6798*ef5ccd6cSJohn Marino shndx = SHN_ABS;
67995796c8dcSSimon Schubert break;
68005796c8dcSSimon Schubert }
68015796c8dcSSimon Schubert }
68025796c8dcSSimon Schubert else
68035796c8dcSSimon Schubert {
68045796c8dcSSimon Schubert shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
68055796c8dcSSimon Schubert
68065796c8dcSSimon Schubert if (shndx == SHN_BAD)
68075796c8dcSSimon Schubert {
68085796c8dcSSimon Schubert asection *sec2;
68095796c8dcSSimon Schubert
68105796c8dcSSimon Schubert /* Writing this would be a hell of a lot easier if
68115796c8dcSSimon Schubert we had some decent documentation on bfd, and
68125796c8dcSSimon Schubert knew what to expect of the library, and what to
68135796c8dcSSimon Schubert demand of applications. For example, it
68145796c8dcSSimon Schubert appears that `objcopy' might not set the
68155796c8dcSSimon Schubert section of a symbol to be a section that is
68165796c8dcSSimon Schubert actually in the output file. */
68175796c8dcSSimon Schubert sec2 = bfd_get_section_by_name (abfd, sec->name);
68185796c8dcSSimon Schubert if (sec2 == NULL)
68195796c8dcSSimon Schubert {
68205796c8dcSSimon Schubert _bfd_error_handler (_("\
68215796c8dcSSimon Schubert Unable to find equivalent output section for symbol '%s' from section '%s'"),
68225796c8dcSSimon Schubert syms[idx]->name ? syms[idx]->name : "<Local sym>",
68235796c8dcSSimon Schubert sec->name);
68245796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation);
68255796c8dcSSimon Schubert _bfd_stringtab_free (stt);
68265796c8dcSSimon Schubert return FALSE;
68275796c8dcSSimon Schubert }
68285796c8dcSSimon Schubert
68295796c8dcSSimon Schubert shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
68305796c8dcSSimon Schubert BFD_ASSERT (shndx != SHN_BAD);
68315796c8dcSSimon Schubert }
68325796c8dcSSimon Schubert }
68335796c8dcSSimon Schubert
68345796c8dcSSimon Schubert sym.st_shndx = shndx;
68355796c8dcSSimon Schubert }
68365796c8dcSSimon Schubert
68375796c8dcSSimon Schubert if ((flags & BSF_THREAD_LOCAL) != 0)
68385796c8dcSSimon Schubert type = STT_TLS;
68395796c8dcSSimon Schubert else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
68405796c8dcSSimon Schubert type = STT_GNU_IFUNC;
68415796c8dcSSimon Schubert else if ((flags & BSF_FUNCTION) != 0)
68425796c8dcSSimon Schubert type = STT_FUNC;
68435796c8dcSSimon Schubert else if ((flags & BSF_OBJECT) != 0)
68445796c8dcSSimon Schubert type = STT_OBJECT;
68455796c8dcSSimon Schubert else if ((flags & BSF_RELC) != 0)
68465796c8dcSSimon Schubert type = STT_RELC;
68475796c8dcSSimon Schubert else if ((flags & BSF_SRELC) != 0)
68485796c8dcSSimon Schubert type = STT_SRELC;
68495796c8dcSSimon Schubert else
68505796c8dcSSimon Schubert type = STT_NOTYPE;
68515796c8dcSSimon Schubert
68525796c8dcSSimon Schubert if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
68535796c8dcSSimon Schubert type = STT_TLS;
68545796c8dcSSimon Schubert
68555796c8dcSSimon Schubert /* Processor-specific types. */
68565796c8dcSSimon Schubert if (type_ptr != NULL
68575796c8dcSSimon Schubert && bed->elf_backend_get_symbol_type)
68585796c8dcSSimon Schubert type = ((*bed->elf_backend_get_symbol_type)
68595796c8dcSSimon Schubert (&type_ptr->internal_elf_sym, type));
68605796c8dcSSimon Schubert
68615796c8dcSSimon Schubert if (flags & BSF_SECTION_SYM)
68625796c8dcSSimon Schubert {
68635796c8dcSSimon Schubert if (flags & BSF_GLOBAL)
68645796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
68655796c8dcSSimon Schubert else
68665796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
68675796c8dcSSimon Schubert }
68685796c8dcSSimon Schubert else if (bfd_is_com_section (syms[idx]->section))
68695796c8dcSSimon Schubert {
68705796c8dcSSimon Schubert #ifdef USE_STT_COMMON
68715796c8dcSSimon Schubert if (type == STT_OBJECT)
68725796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
68735796c8dcSSimon Schubert else
68745796c8dcSSimon Schubert #endif
68755796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
68765796c8dcSSimon Schubert }
68775796c8dcSSimon Schubert else if (bfd_is_und_section (syms[idx]->section))
68785796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
68795796c8dcSSimon Schubert ? STB_WEAK
68805796c8dcSSimon Schubert : STB_GLOBAL),
68815796c8dcSSimon Schubert type);
68825796c8dcSSimon Schubert else if (flags & BSF_FILE)
68835796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
68845796c8dcSSimon Schubert else
68855796c8dcSSimon Schubert {
68865796c8dcSSimon Schubert int bind = STB_LOCAL;
68875796c8dcSSimon Schubert
68885796c8dcSSimon Schubert if (flags & BSF_LOCAL)
68895796c8dcSSimon Schubert bind = STB_LOCAL;
68905796c8dcSSimon Schubert else if (flags & BSF_GNU_UNIQUE)
68915796c8dcSSimon Schubert bind = STB_GNU_UNIQUE;
68925796c8dcSSimon Schubert else if (flags & BSF_WEAK)
68935796c8dcSSimon Schubert bind = STB_WEAK;
68945796c8dcSSimon Schubert else if (flags & BSF_GLOBAL)
68955796c8dcSSimon Schubert bind = STB_GLOBAL;
68965796c8dcSSimon Schubert
68975796c8dcSSimon Schubert sym.st_info = ELF_ST_INFO (bind, type);
68985796c8dcSSimon Schubert }
68995796c8dcSSimon Schubert
69005796c8dcSSimon Schubert if (type_ptr != NULL)
6901c50c785cSJohn Marino {
69025796c8dcSSimon Schubert sym.st_other = type_ptr->internal_elf_sym.st_other;
6903c50c785cSJohn Marino sym.st_target_internal
6904c50c785cSJohn Marino = type_ptr->internal_elf_sym.st_target_internal;
6905c50c785cSJohn Marino }
69065796c8dcSSimon Schubert else
6907c50c785cSJohn Marino {
69085796c8dcSSimon Schubert sym.st_other = 0;
6909c50c785cSJohn Marino sym.st_target_internal = 0;
6910c50c785cSJohn Marino }
69115796c8dcSSimon Schubert
69125796c8dcSSimon Schubert bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
69135796c8dcSSimon Schubert outbound_syms += bed->s->sizeof_sym;
69145796c8dcSSimon Schubert if (outbound_shndx != NULL)
69155796c8dcSSimon Schubert outbound_shndx += sizeof (Elf_External_Sym_Shndx);
69165796c8dcSSimon Schubert }
69175796c8dcSSimon Schubert
69185796c8dcSSimon Schubert *sttp = stt;
69195796c8dcSSimon Schubert symstrtab_hdr->sh_size = _bfd_stringtab_size (stt);
69205796c8dcSSimon Schubert symstrtab_hdr->sh_type = SHT_STRTAB;
69215796c8dcSSimon Schubert
69225796c8dcSSimon Schubert symstrtab_hdr->sh_flags = 0;
69235796c8dcSSimon Schubert symstrtab_hdr->sh_addr = 0;
69245796c8dcSSimon Schubert symstrtab_hdr->sh_entsize = 0;
69255796c8dcSSimon Schubert symstrtab_hdr->sh_link = 0;
69265796c8dcSSimon Schubert symstrtab_hdr->sh_info = 0;
69275796c8dcSSimon Schubert symstrtab_hdr->sh_addralign = 1;
69285796c8dcSSimon Schubert
69295796c8dcSSimon Schubert return TRUE;
69305796c8dcSSimon Schubert }
69315796c8dcSSimon Schubert
69325796c8dcSSimon Schubert /* Return the number of bytes required to hold the symtab vector.
69335796c8dcSSimon Schubert
69345796c8dcSSimon Schubert Note that we base it on the count plus 1, since we will null terminate
69355796c8dcSSimon Schubert the vector allocated based on this size. However, the ELF symbol table
69365796c8dcSSimon Schubert always has a dummy entry as symbol #0, so it ends up even. */
69375796c8dcSSimon Schubert
69385796c8dcSSimon Schubert long
_bfd_elf_get_symtab_upper_bound(bfd * abfd)69395796c8dcSSimon Schubert _bfd_elf_get_symtab_upper_bound (bfd *abfd)
69405796c8dcSSimon Schubert {
69415796c8dcSSimon Schubert long symcount;
69425796c8dcSSimon Schubert long symtab_size;
69435796c8dcSSimon Schubert Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
69445796c8dcSSimon Schubert
69455796c8dcSSimon Schubert symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
69465796c8dcSSimon Schubert symtab_size = (symcount + 1) * (sizeof (asymbol *));
69475796c8dcSSimon Schubert if (symcount > 0)
69485796c8dcSSimon Schubert symtab_size -= sizeof (asymbol *);
69495796c8dcSSimon Schubert
69505796c8dcSSimon Schubert return symtab_size;
69515796c8dcSSimon Schubert }
69525796c8dcSSimon Schubert
69535796c8dcSSimon Schubert long
_bfd_elf_get_dynamic_symtab_upper_bound(bfd * abfd)69545796c8dcSSimon Schubert _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
69555796c8dcSSimon Schubert {
69565796c8dcSSimon Schubert long symcount;
69575796c8dcSSimon Schubert long symtab_size;
69585796c8dcSSimon Schubert Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
69595796c8dcSSimon Schubert
69605796c8dcSSimon Schubert if (elf_dynsymtab (abfd) == 0)
69615796c8dcSSimon Schubert {
69625796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation);
69635796c8dcSSimon Schubert return -1;
69645796c8dcSSimon Schubert }
69655796c8dcSSimon Schubert
69665796c8dcSSimon Schubert symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
69675796c8dcSSimon Schubert symtab_size = (symcount + 1) * (sizeof (asymbol *));
69685796c8dcSSimon Schubert if (symcount > 0)
69695796c8dcSSimon Schubert symtab_size -= sizeof (asymbol *);
69705796c8dcSSimon Schubert
69715796c8dcSSimon Schubert return symtab_size;
69725796c8dcSSimon Schubert }
69735796c8dcSSimon Schubert
69745796c8dcSSimon Schubert long
_bfd_elf_get_reloc_upper_bound(bfd * abfd ATTRIBUTE_UNUSED,sec_ptr asect)69755796c8dcSSimon Schubert _bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
69765796c8dcSSimon Schubert sec_ptr asect)
69775796c8dcSSimon Schubert {
69785796c8dcSSimon Schubert return (asect->reloc_count + 1) * sizeof (arelent *);
69795796c8dcSSimon Schubert }
69805796c8dcSSimon Schubert
69815796c8dcSSimon Schubert /* Canonicalize the relocs. */
69825796c8dcSSimon Schubert
69835796c8dcSSimon Schubert long
_bfd_elf_canonicalize_reloc(bfd * abfd,sec_ptr section,arelent ** relptr,asymbol ** symbols)69845796c8dcSSimon Schubert _bfd_elf_canonicalize_reloc (bfd *abfd,
69855796c8dcSSimon Schubert sec_ptr section,
69865796c8dcSSimon Schubert arelent **relptr,
69875796c8dcSSimon Schubert asymbol **symbols)
69885796c8dcSSimon Schubert {
69895796c8dcSSimon Schubert arelent *tblptr;
69905796c8dcSSimon Schubert unsigned int i;
69915796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
69925796c8dcSSimon Schubert
69935796c8dcSSimon Schubert if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
69945796c8dcSSimon Schubert return -1;
69955796c8dcSSimon Schubert
69965796c8dcSSimon Schubert tblptr = section->relocation;
69975796c8dcSSimon Schubert for (i = 0; i < section->reloc_count; i++)
69985796c8dcSSimon Schubert *relptr++ = tblptr++;
69995796c8dcSSimon Schubert
70005796c8dcSSimon Schubert *relptr = NULL;
70015796c8dcSSimon Schubert
70025796c8dcSSimon Schubert return section->reloc_count;
70035796c8dcSSimon Schubert }
70045796c8dcSSimon Schubert
70055796c8dcSSimon Schubert long
_bfd_elf_canonicalize_symtab(bfd * abfd,asymbol ** allocation)70065796c8dcSSimon Schubert _bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
70075796c8dcSSimon Schubert {
70085796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
70095796c8dcSSimon Schubert long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);
70105796c8dcSSimon Schubert
70115796c8dcSSimon Schubert if (symcount >= 0)
70125796c8dcSSimon Schubert bfd_get_symcount (abfd) = symcount;
70135796c8dcSSimon Schubert return symcount;
70145796c8dcSSimon Schubert }
70155796c8dcSSimon Schubert
70165796c8dcSSimon Schubert long
_bfd_elf_canonicalize_dynamic_symtab(bfd * abfd,asymbol ** allocation)70175796c8dcSSimon Schubert _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
70185796c8dcSSimon Schubert asymbol **allocation)
70195796c8dcSSimon Schubert {
70205796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
70215796c8dcSSimon Schubert long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);
70225796c8dcSSimon Schubert
70235796c8dcSSimon Schubert if (symcount >= 0)
70245796c8dcSSimon Schubert bfd_get_dynamic_symcount (abfd) = symcount;
70255796c8dcSSimon Schubert return symcount;
70265796c8dcSSimon Schubert }
70275796c8dcSSimon Schubert
70285796c8dcSSimon Schubert /* Return the size required for the dynamic reloc entries. Any loadable
70295796c8dcSSimon Schubert section that was actually installed in the BFD, and has type SHT_REL
70305796c8dcSSimon Schubert or SHT_RELA, and uses the dynamic symbol table, is considered to be a
70315796c8dcSSimon Schubert dynamic reloc section. */
70325796c8dcSSimon Schubert
70335796c8dcSSimon Schubert long
_bfd_elf_get_dynamic_reloc_upper_bound(bfd * abfd)70345796c8dcSSimon Schubert _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
70355796c8dcSSimon Schubert {
70365796c8dcSSimon Schubert long ret;
70375796c8dcSSimon Schubert asection *s;
70385796c8dcSSimon Schubert
70395796c8dcSSimon Schubert if (elf_dynsymtab (abfd) == 0)
70405796c8dcSSimon Schubert {
70415796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation);
70425796c8dcSSimon Schubert return -1;
70435796c8dcSSimon Schubert }
70445796c8dcSSimon Schubert
70455796c8dcSSimon Schubert ret = sizeof (arelent *);
70465796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
70475796c8dcSSimon Schubert if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
70485796c8dcSSimon Schubert && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
70495796c8dcSSimon Schubert || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
70505796c8dcSSimon Schubert ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
70515796c8dcSSimon Schubert * sizeof (arelent *));
70525796c8dcSSimon Schubert
70535796c8dcSSimon Schubert return ret;
70545796c8dcSSimon Schubert }
70555796c8dcSSimon Schubert
70565796c8dcSSimon Schubert /* Canonicalize the dynamic relocation entries. Note that we return the
70575796c8dcSSimon Schubert dynamic relocations as a single block, although they are actually
70585796c8dcSSimon Schubert associated with particular sections; the interface, which was
70595796c8dcSSimon Schubert designed for SunOS style shared libraries, expects that there is only
70605796c8dcSSimon Schubert one set of dynamic relocs. Any loadable section that was actually
70615796c8dcSSimon Schubert installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the
70625796c8dcSSimon Schubert dynamic symbol table, is considered to be a dynamic reloc section. */
70635796c8dcSSimon Schubert
70645796c8dcSSimon Schubert long
_bfd_elf_canonicalize_dynamic_reloc(bfd * abfd,arelent ** storage,asymbol ** syms)70655796c8dcSSimon Schubert _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
70665796c8dcSSimon Schubert arelent **storage,
70675796c8dcSSimon Schubert asymbol **syms)
70685796c8dcSSimon Schubert {
70695796c8dcSSimon Schubert bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
70705796c8dcSSimon Schubert asection *s;
70715796c8dcSSimon Schubert long ret;
70725796c8dcSSimon Schubert
70735796c8dcSSimon Schubert if (elf_dynsymtab (abfd) == 0)
70745796c8dcSSimon Schubert {
70755796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation);
70765796c8dcSSimon Schubert return -1;
70775796c8dcSSimon Schubert }
70785796c8dcSSimon Schubert
70795796c8dcSSimon Schubert slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
70805796c8dcSSimon Schubert ret = 0;
70815796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
70825796c8dcSSimon Schubert {
70835796c8dcSSimon Schubert if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
70845796c8dcSSimon Schubert && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
70855796c8dcSSimon Schubert || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
70865796c8dcSSimon Schubert {
70875796c8dcSSimon Schubert arelent *p;
70885796c8dcSSimon Schubert long count, i;
70895796c8dcSSimon Schubert
70905796c8dcSSimon Schubert if (! (*slurp_relocs) (abfd, s, syms, TRUE))
70915796c8dcSSimon Schubert return -1;
70925796c8dcSSimon Schubert count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
70935796c8dcSSimon Schubert p = s->relocation;
70945796c8dcSSimon Schubert for (i = 0; i < count; i++)
70955796c8dcSSimon Schubert *storage++ = p++;
70965796c8dcSSimon Schubert ret += count;
70975796c8dcSSimon Schubert }
70985796c8dcSSimon Schubert }
70995796c8dcSSimon Schubert
71005796c8dcSSimon Schubert *storage = NULL;
71015796c8dcSSimon Schubert
71025796c8dcSSimon Schubert return ret;
71035796c8dcSSimon Schubert }
71045796c8dcSSimon Schubert
71055796c8dcSSimon Schubert /* Read in the version information. */
71065796c8dcSSimon Schubert
71075796c8dcSSimon Schubert bfd_boolean
_bfd_elf_slurp_version_tables(bfd * abfd,bfd_boolean default_imported_symver)71085796c8dcSSimon Schubert _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
71095796c8dcSSimon Schubert {
71105796c8dcSSimon Schubert bfd_byte *contents = NULL;
71115796c8dcSSimon Schubert unsigned int freeidx = 0;
71125796c8dcSSimon Schubert
71135796c8dcSSimon Schubert if (elf_dynverref (abfd) != 0)
71145796c8dcSSimon Schubert {
71155796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
71165796c8dcSSimon Schubert Elf_External_Verneed *everneed;
71175796c8dcSSimon Schubert Elf_Internal_Verneed *iverneed;
71185796c8dcSSimon Schubert unsigned int i;
71195796c8dcSSimon Schubert bfd_byte *contents_end;
71205796c8dcSSimon Schubert
71215796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->dynverref_hdr;
71225796c8dcSSimon Schubert
71235796c8dcSSimon Schubert elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
71245796c8dcSSimon Schubert bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
71255796c8dcSSimon Schubert if (elf_tdata (abfd)->verref == NULL)
71265796c8dcSSimon Schubert goto error_return;
71275796c8dcSSimon Schubert
71285796c8dcSSimon Schubert elf_tdata (abfd)->cverrefs = hdr->sh_info;
71295796c8dcSSimon Schubert
71305796c8dcSSimon Schubert contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
71315796c8dcSSimon Schubert if (contents == NULL)
71325796c8dcSSimon Schubert {
71335796c8dcSSimon Schubert error_return_verref:
71345796c8dcSSimon Schubert elf_tdata (abfd)->verref = NULL;
71355796c8dcSSimon Schubert elf_tdata (abfd)->cverrefs = 0;
71365796c8dcSSimon Schubert goto error_return;
71375796c8dcSSimon Schubert }
71385796c8dcSSimon Schubert if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
71395796c8dcSSimon Schubert || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
71405796c8dcSSimon Schubert goto error_return_verref;
71415796c8dcSSimon Schubert
71425796c8dcSSimon Schubert if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
71435796c8dcSSimon Schubert goto error_return_verref;
71445796c8dcSSimon Schubert
71455796c8dcSSimon Schubert BFD_ASSERT (sizeof (Elf_External_Verneed)
71465796c8dcSSimon Schubert == sizeof (Elf_External_Vernaux));
71475796c8dcSSimon Schubert contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
71485796c8dcSSimon Schubert everneed = (Elf_External_Verneed *) contents;
71495796c8dcSSimon Schubert iverneed = elf_tdata (abfd)->verref;
71505796c8dcSSimon Schubert for (i = 0; i < hdr->sh_info; i++, iverneed++)
71515796c8dcSSimon Schubert {
71525796c8dcSSimon Schubert Elf_External_Vernaux *evernaux;
71535796c8dcSSimon Schubert Elf_Internal_Vernaux *ivernaux;
71545796c8dcSSimon Schubert unsigned int j;
71555796c8dcSSimon Schubert
71565796c8dcSSimon Schubert _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
71575796c8dcSSimon Schubert
71585796c8dcSSimon Schubert iverneed->vn_bfd = abfd;
71595796c8dcSSimon Schubert
71605796c8dcSSimon Schubert iverneed->vn_filename =
71615796c8dcSSimon Schubert bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
71625796c8dcSSimon Schubert iverneed->vn_file);
71635796c8dcSSimon Schubert if (iverneed->vn_filename == NULL)
71645796c8dcSSimon Schubert goto error_return_verref;
71655796c8dcSSimon Schubert
71665796c8dcSSimon Schubert if (iverneed->vn_cnt == 0)
71675796c8dcSSimon Schubert iverneed->vn_auxptr = NULL;
71685796c8dcSSimon Schubert else
71695796c8dcSSimon Schubert {
71705796c8dcSSimon Schubert iverneed->vn_auxptr = (struct elf_internal_vernaux *)
71715796c8dcSSimon Schubert bfd_alloc2 (abfd, iverneed->vn_cnt,
71725796c8dcSSimon Schubert sizeof (Elf_Internal_Vernaux));
71735796c8dcSSimon Schubert if (iverneed->vn_auxptr == NULL)
71745796c8dcSSimon Schubert goto error_return_verref;
71755796c8dcSSimon Schubert }
71765796c8dcSSimon Schubert
71775796c8dcSSimon Schubert if (iverneed->vn_aux
71785796c8dcSSimon Schubert > (size_t) (contents_end - (bfd_byte *) everneed))
71795796c8dcSSimon Schubert goto error_return_verref;
71805796c8dcSSimon Schubert
71815796c8dcSSimon Schubert evernaux = ((Elf_External_Vernaux *)
71825796c8dcSSimon Schubert ((bfd_byte *) everneed + iverneed->vn_aux));
71835796c8dcSSimon Schubert ivernaux = iverneed->vn_auxptr;
71845796c8dcSSimon Schubert for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
71855796c8dcSSimon Schubert {
71865796c8dcSSimon Schubert _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
71875796c8dcSSimon Schubert
71885796c8dcSSimon Schubert ivernaux->vna_nodename =
71895796c8dcSSimon Schubert bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
71905796c8dcSSimon Schubert ivernaux->vna_name);
71915796c8dcSSimon Schubert if (ivernaux->vna_nodename == NULL)
71925796c8dcSSimon Schubert goto error_return_verref;
71935796c8dcSSimon Schubert
71945796c8dcSSimon Schubert if (j + 1 < iverneed->vn_cnt)
71955796c8dcSSimon Schubert ivernaux->vna_nextptr = ivernaux + 1;
71965796c8dcSSimon Schubert else
71975796c8dcSSimon Schubert ivernaux->vna_nextptr = NULL;
71985796c8dcSSimon Schubert
71995796c8dcSSimon Schubert if (ivernaux->vna_next
72005796c8dcSSimon Schubert > (size_t) (contents_end - (bfd_byte *) evernaux))
72015796c8dcSSimon Schubert goto error_return_verref;
72025796c8dcSSimon Schubert
72035796c8dcSSimon Schubert evernaux = ((Elf_External_Vernaux *)
72045796c8dcSSimon Schubert ((bfd_byte *) evernaux + ivernaux->vna_next));
72055796c8dcSSimon Schubert
72065796c8dcSSimon Schubert if (ivernaux->vna_other > freeidx)
72075796c8dcSSimon Schubert freeidx = ivernaux->vna_other;
72085796c8dcSSimon Schubert }
72095796c8dcSSimon Schubert
72105796c8dcSSimon Schubert if (i + 1 < hdr->sh_info)
72115796c8dcSSimon Schubert iverneed->vn_nextref = iverneed + 1;
72125796c8dcSSimon Schubert else
72135796c8dcSSimon Schubert iverneed->vn_nextref = NULL;
72145796c8dcSSimon Schubert
72155796c8dcSSimon Schubert if (iverneed->vn_next
72165796c8dcSSimon Schubert > (size_t) (contents_end - (bfd_byte *) everneed))
72175796c8dcSSimon Schubert goto error_return_verref;
72185796c8dcSSimon Schubert
72195796c8dcSSimon Schubert everneed = ((Elf_External_Verneed *)
72205796c8dcSSimon Schubert ((bfd_byte *) everneed + iverneed->vn_next));
72215796c8dcSSimon Schubert }
72225796c8dcSSimon Schubert
72235796c8dcSSimon Schubert free (contents);
72245796c8dcSSimon Schubert contents = NULL;
72255796c8dcSSimon Schubert }
72265796c8dcSSimon Schubert
72275796c8dcSSimon Schubert if (elf_dynverdef (abfd) != 0)
72285796c8dcSSimon Schubert {
72295796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
72305796c8dcSSimon Schubert Elf_External_Verdef *everdef;
72315796c8dcSSimon Schubert Elf_Internal_Verdef *iverdef;
72325796c8dcSSimon Schubert Elf_Internal_Verdef *iverdefarr;
72335796c8dcSSimon Schubert Elf_Internal_Verdef iverdefmem;
72345796c8dcSSimon Schubert unsigned int i;
72355796c8dcSSimon Schubert unsigned int maxidx;
72365796c8dcSSimon Schubert bfd_byte *contents_end_def, *contents_end_aux;
72375796c8dcSSimon Schubert
72385796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->dynverdef_hdr;
72395796c8dcSSimon Schubert
72405796c8dcSSimon Schubert contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
72415796c8dcSSimon Schubert if (contents == NULL)
72425796c8dcSSimon Schubert goto error_return;
72435796c8dcSSimon Schubert if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
72445796c8dcSSimon Schubert || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
72455796c8dcSSimon Schubert goto error_return;
72465796c8dcSSimon Schubert
72475796c8dcSSimon Schubert if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
72485796c8dcSSimon Schubert goto error_return;
72495796c8dcSSimon Schubert
72505796c8dcSSimon Schubert BFD_ASSERT (sizeof (Elf_External_Verdef)
72515796c8dcSSimon Schubert >= sizeof (Elf_External_Verdaux));
72525796c8dcSSimon Schubert contents_end_def = contents + hdr->sh_size
72535796c8dcSSimon Schubert - sizeof (Elf_External_Verdef);
72545796c8dcSSimon Schubert contents_end_aux = contents + hdr->sh_size
72555796c8dcSSimon Schubert - sizeof (Elf_External_Verdaux);
72565796c8dcSSimon Schubert
72575796c8dcSSimon Schubert /* We know the number of entries in the section but not the maximum
72585796c8dcSSimon Schubert index. Therefore we have to run through all entries and find
72595796c8dcSSimon Schubert the maximum. */
72605796c8dcSSimon Schubert everdef = (Elf_External_Verdef *) contents;
72615796c8dcSSimon Schubert maxidx = 0;
72625796c8dcSSimon Schubert for (i = 0; i < hdr->sh_info; ++i)
72635796c8dcSSimon Schubert {
72645796c8dcSSimon Schubert _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
72655796c8dcSSimon Schubert
72665796c8dcSSimon Schubert if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
72675796c8dcSSimon Schubert maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
72685796c8dcSSimon Schubert
72695796c8dcSSimon Schubert if (iverdefmem.vd_next
72705796c8dcSSimon Schubert > (size_t) (contents_end_def - (bfd_byte *) everdef))
72715796c8dcSSimon Schubert goto error_return;
72725796c8dcSSimon Schubert
72735796c8dcSSimon Schubert everdef = ((Elf_External_Verdef *)
72745796c8dcSSimon Schubert ((bfd_byte *) everdef + iverdefmem.vd_next));
72755796c8dcSSimon Schubert }
72765796c8dcSSimon Schubert
72775796c8dcSSimon Schubert if (default_imported_symver)
72785796c8dcSSimon Schubert {
72795796c8dcSSimon Schubert if (freeidx > maxidx)
72805796c8dcSSimon Schubert maxidx = ++freeidx;
72815796c8dcSSimon Schubert else
72825796c8dcSSimon Schubert freeidx = ++maxidx;
72835796c8dcSSimon Schubert }
72845796c8dcSSimon Schubert elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
72855796c8dcSSimon Schubert bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef));
72865796c8dcSSimon Schubert if (elf_tdata (abfd)->verdef == NULL)
72875796c8dcSSimon Schubert goto error_return;
72885796c8dcSSimon Schubert
72895796c8dcSSimon Schubert elf_tdata (abfd)->cverdefs = maxidx;
72905796c8dcSSimon Schubert
72915796c8dcSSimon Schubert everdef = (Elf_External_Verdef *) contents;
72925796c8dcSSimon Schubert iverdefarr = elf_tdata (abfd)->verdef;
72935796c8dcSSimon Schubert for (i = 0; i < hdr->sh_info; i++)
72945796c8dcSSimon Schubert {
72955796c8dcSSimon Schubert Elf_External_Verdaux *everdaux;
72965796c8dcSSimon Schubert Elf_Internal_Verdaux *iverdaux;
72975796c8dcSSimon Schubert unsigned int j;
72985796c8dcSSimon Schubert
72995796c8dcSSimon Schubert _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
73005796c8dcSSimon Schubert
73015796c8dcSSimon Schubert if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
73025796c8dcSSimon Schubert {
73035796c8dcSSimon Schubert error_return_verdef:
73045796c8dcSSimon Schubert elf_tdata (abfd)->verdef = NULL;
73055796c8dcSSimon Schubert elf_tdata (abfd)->cverdefs = 0;
73065796c8dcSSimon Schubert goto error_return;
73075796c8dcSSimon Schubert }
73085796c8dcSSimon Schubert
73095796c8dcSSimon Schubert iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
73105796c8dcSSimon Schubert memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
73115796c8dcSSimon Schubert
73125796c8dcSSimon Schubert iverdef->vd_bfd = abfd;
73135796c8dcSSimon Schubert
73145796c8dcSSimon Schubert if (iverdef->vd_cnt == 0)
73155796c8dcSSimon Schubert iverdef->vd_auxptr = NULL;
73165796c8dcSSimon Schubert else
73175796c8dcSSimon Schubert {
73185796c8dcSSimon Schubert iverdef->vd_auxptr = (struct elf_internal_verdaux *)
73195796c8dcSSimon Schubert bfd_alloc2 (abfd, iverdef->vd_cnt,
73205796c8dcSSimon Schubert sizeof (Elf_Internal_Verdaux));
73215796c8dcSSimon Schubert if (iverdef->vd_auxptr == NULL)
73225796c8dcSSimon Schubert goto error_return_verdef;
73235796c8dcSSimon Schubert }
73245796c8dcSSimon Schubert
73255796c8dcSSimon Schubert if (iverdef->vd_aux
73265796c8dcSSimon Schubert > (size_t) (contents_end_aux - (bfd_byte *) everdef))
73275796c8dcSSimon Schubert goto error_return_verdef;
73285796c8dcSSimon Schubert
73295796c8dcSSimon Schubert everdaux = ((Elf_External_Verdaux *)
73305796c8dcSSimon Schubert ((bfd_byte *) everdef + iverdef->vd_aux));
73315796c8dcSSimon Schubert iverdaux = iverdef->vd_auxptr;
73325796c8dcSSimon Schubert for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
73335796c8dcSSimon Schubert {
73345796c8dcSSimon Schubert _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);
73355796c8dcSSimon Schubert
73365796c8dcSSimon Schubert iverdaux->vda_nodename =
73375796c8dcSSimon Schubert bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
73385796c8dcSSimon Schubert iverdaux->vda_name);
73395796c8dcSSimon Schubert if (iverdaux->vda_nodename == NULL)
73405796c8dcSSimon Schubert goto error_return_verdef;
73415796c8dcSSimon Schubert
73425796c8dcSSimon Schubert if (j + 1 < iverdef->vd_cnt)
73435796c8dcSSimon Schubert iverdaux->vda_nextptr = iverdaux + 1;
73445796c8dcSSimon Schubert else
73455796c8dcSSimon Schubert iverdaux->vda_nextptr = NULL;
73465796c8dcSSimon Schubert
73475796c8dcSSimon Schubert if (iverdaux->vda_next
73485796c8dcSSimon Schubert > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
73495796c8dcSSimon Schubert goto error_return_verdef;
73505796c8dcSSimon Schubert
73515796c8dcSSimon Schubert everdaux = ((Elf_External_Verdaux *)
73525796c8dcSSimon Schubert ((bfd_byte *) everdaux + iverdaux->vda_next));
73535796c8dcSSimon Schubert }
73545796c8dcSSimon Schubert
73555796c8dcSSimon Schubert if (iverdef->vd_cnt)
73565796c8dcSSimon Schubert iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
73575796c8dcSSimon Schubert
73585796c8dcSSimon Schubert if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
73595796c8dcSSimon Schubert iverdef->vd_nextdef = iverdef + 1;
73605796c8dcSSimon Schubert else
73615796c8dcSSimon Schubert iverdef->vd_nextdef = NULL;
73625796c8dcSSimon Schubert
73635796c8dcSSimon Schubert everdef = ((Elf_External_Verdef *)
73645796c8dcSSimon Schubert ((bfd_byte *) everdef + iverdef->vd_next));
73655796c8dcSSimon Schubert }
73665796c8dcSSimon Schubert
73675796c8dcSSimon Schubert free (contents);
73685796c8dcSSimon Schubert contents = NULL;
73695796c8dcSSimon Schubert }
73705796c8dcSSimon Schubert else if (default_imported_symver)
73715796c8dcSSimon Schubert {
73725796c8dcSSimon Schubert if (freeidx < 3)
73735796c8dcSSimon Schubert freeidx = 3;
73745796c8dcSSimon Schubert else
73755796c8dcSSimon Schubert freeidx++;
73765796c8dcSSimon Schubert
73775796c8dcSSimon Schubert elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
73785796c8dcSSimon Schubert bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef));
73795796c8dcSSimon Schubert if (elf_tdata (abfd)->verdef == NULL)
73805796c8dcSSimon Schubert goto error_return;
73815796c8dcSSimon Schubert
73825796c8dcSSimon Schubert elf_tdata (abfd)->cverdefs = freeidx;
73835796c8dcSSimon Schubert }
73845796c8dcSSimon Schubert
73855796c8dcSSimon Schubert /* Create a default version based on the soname. */
73865796c8dcSSimon Schubert if (default_imported_symver)
73875796c8dcSSimon Schubert {
73885796c8dcSSimon Schubert Elf_Internal_Verdef *iverdef;
73895796c8dcSSimon Schubert Elf_Internal_Verdaux *iverdaux;
73905796c8dcSSimon Schubert
7391*ef5ccd6cSJohn Marino iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];
73925796c8dcSSimon Schubert
73935796c8dcSSimon Schubert iverdef->vd_version = VER_DEF_CURRENT;
73945796c8dcSSimon Schubert iverdef->vd_flags = 0;
73955796c8dcSSimon Schubert iverdef->vd_ndx = freeidx;
73965796c8dcSSimon Schubert iverdef->vd_cnt = 1;
73975796c8dcSSimon Schubert
73985796c8dcSSimon Schubert iverdef->vd_bfd = abfd;
73995796c8dcSSimon Schubert
74005796c8dcSSimon Schubert iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
74015796c8dcSSimon Schubert if (iverdef->vd_nodename == NULL)
74025796c8dcSSimon Schubert goto error_return_verdef;
74035796c8dcSSimon Schubert iverdef->vd_nextdef = NULL;
74045796c8dcSSimon Schubert iverdef->vd_auxptr = (struct elf_internal_verdaux *)
74055796c8dcSSimon Schubert bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
74065796c8dcSSimon Schubert if (iverdef->vd_auxptr == NULL)
74075796c8dcSSimon Schubert goto error_return_verdef;
74085796c8dcSSimon Schubert
74095796c8dcSSimon Schubert iverdaux = iverdef->vd_auxptr;
74105796c8dcSSimon Schubert iverdaux->vda_nodename = iverdef->vd_nodename;
74115796c8dcSSimon Schubert iverdaux->vda_nextptr = NULL;
74125796c8dcSSimon Schubert }
74135796c8dcSSimon Schubert
74145796c8dcSSimon Schubert return TRUE;
74155796c8dcSSimon Schubert
74165796c8dcSSimon Schubert error_return:
74175796c8dcSSimon Schubert if (contents != NULL)
74185796c8dcSSimon Schubert free (contents);
74195796c8dcSSimon Schubert return FALSE;
74205796c8dcSSimon Schubert }
74215796c8dcSSimon Schubert
74225796c8dcSSimon Schubert asymbol *
_bfd_elf_make_empty_symbol(bfd * abfd)74235796c8dcSSimon Schubert _bfd_elf_make_empty_symbol (bfd *abfd)
74245796c8dcSSimon Schubert {
74255796c8dcSSimon Schubert elf_symbol_type *newsym;
74265796c8dcSSimon Schubert bfd_size_type amt = sizeof (elf_symbol_type);
74275796c8dcSSimon Schubert
74285796c8dcSSimon Schubert newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt);
74295796c8dcSSimon Schubert if (!newsym)
74305796c8dcSSimon Schubert return NULL;
74315796c8dcSSimon Schubert else
74325796c8dcSSimon Schubert {
74335796c8dcSSimon Schubert newsym->symbol.the_bfd = abfd;
74345796c8dcSSimon Schubert return &newsym->symbol;
74355796c8dcSSimon Schubert }
74365796c8dcSSimon Schubert }
74375796c8dcSSimon Schubert
74385796c8dcSSimon Schubert void
_bfd_elf_get_symbol_info(bfd * abfd ATTRIBUTE_UNUSED,asymbol * symbol,symbol_info * ret)74395796c8dcSSimon Schubert _bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
74405796c8dcSSimon Schubert asymbol *symbol,
74415796c8dcSSimon Schubert symbol_info *ret)
74425796c8dcSSimon Schubert {
74435796c8dcSSimon Schubert bfd_symbol_info (symbol, ret);
74445796c8dcSSimon Schubert }
74455796c8dcSSimon Schubert
74465796c8dcSSimon Schubert /* Return whether a symbol name implies a local symbol. Most targets
74475796c8dcSSimon Schubert use this function for the is_local_label_name entry point, but some
74485796c8dcSSimon Schubert override it. */
74495796c8dcSSimon Schubert
74505796c8dcSSimon Schubert bfd_boolean
_bfd_elf_is_local_label_name(bfd * abfd ATTRIBUTE_UNUSED,const char * name)74515796c8dcSSimon Schubert _bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
74525796c8dcSSimon Schubert const char *name)
74535796c8dcSSimon Schubert {
74545796c8dcSSimon Schubert /* Normal local symbols start with ``.L''. */
74555796c8dcSSimon Schubert if (name[0] == '.' && name[1] == 'L')
74565796c8dcSSimon Schubert return TRUE;
74575796c8dcSSimon Schubert
74585796c8dcSSimon Schubert /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
74595796c8dcSSimon Schubert DWARF debugging symbols starting with ``..''. */
74605796c8dcSSimon Schubert if (name[0] == '.' && name[1] == '.')
74615796c8dcSSimon Schubert return TRUE;
74625796c8dcSSimon Schubert
74635796c8dcSSimon Schubert /* gcc will sometimes generate symbols beginning with ``_.L_'' when
74645796c8dcSSimon Schubert emitting DWARF debugging output. I suspect this is actually a
74655796c8dcSSimon Schubert small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
74665796c8dcSSimon Schubert ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
74675796c8dcSSimon Schubert underscore to be emitted on some ELF targets). For ease of use,
74685796c8dcSSimon Schubert we treat such symbols as local. */
74695796c8dcSSimon Schubert if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
74705796c8dcSSimon Schubert return TRUE;
74715796c8dcSSimon Schubert
74725796c8dcSSimon Schubert return FALSE;
74735796c8dcSSimon Schubert }
74745796c8dcSSimon Schubert
74755796c8dcSSimon Schubert alent *
_bfd_elf_get_lineno(bfd * abfd ATTRIBUTE_UNUSED,asymbol * symbol ATTRIBUTE_UNUSED)74765796c8dcSSimon Schubert _bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED,
74775796c8dcSSimon Schubert asymbol *symbol ATTRIBUTE_UNUSED)
74785796c8dcSSimon Schubert {
74795796c8dcSSimon Schubert abort ();
74805796c8dcSSimon Schubert return NULL;
74815796c8dcSSimon Schubert }
74825796c8dcSSimon Schubert
74835796c8dcSSimon Schubert bfd_boolean
_bfd_elf_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long machine)74845796c8dcSSimon Schubert _bfd_elf_set_arch_mach (bfd *abfd,
74855796c8dcSSimon Schubert enum bfd_architecture arch,
74865796c8dcSSimon Schubert unsigned long machine)
74875796c8dcSSimon Schubert {
74885796c8dcSSimon Schubert /* If this isn't the right architecture for this backend, and this
74895796c8dcSSimon Schubert isn't the generic backend, fail. */
74905796c8dcSSimon Schubert if (arch != get_elf_backend_data (abfd)->arch
74915796c8dcSSimon Schubert && arch != bfd_arch_unknown
74925796c8dcSSimon Schubert && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
74935796c8dcSSimon Schubert return FALSE;
74945796c8dcSSimon Schubert
74955796c8dcSSimon Schubert return bfd_default_set_arch_mach (abfd, arch, machine);
74965796c8dcSSimon Schubert }
74975796c8dcSSimon Schubert
74985796c8dcSSimon Schubert /* Find the function to a particular section and offset,
74995796c8dcSSimon Schubert for error reporting. */
75005796c8dcSSimon Schubert
75015796c8dcSSimon Schubert static bfd_boolean
elf_find_function(bfd * abfd,asection * section,asymbol ** symbols,bfd_vma offset,const char ** filename_ptr,const char ** functionname_ptr)75025796c8dcSSimon Schubert elf_find_function (bfd *abfd,
75035796c8dcSSimon Schubert asection *section,
75045796c8dcSSimon Schubert asymbol **symbols,
75055796c8dcSSimon Schubert bfd_vma offset,
75065796c8dcSSimon Schubert const char **filename_ptr,
75075796c8dcSSimon Schubert const char **functionname_ptr)
75085796c8dcSSimon Schubert {
7509*ef5ccd6cSJohn Marino struct elf_find_function_cache
7510*ef5ccd6cSJohn Marino {
7511*ef5ccd6cSJohn Marino asection *last_section;
7512*ef5ccd6cSJohn Marino asymbol *func;
75135796c8dcSSimon Schubert const char *filename;
7514*ef5ccd6cSJohn Marino bfd_size_type func_size;
7515*ef5ccd6cSJohn Marino } *cache;
7516*ef5ccd6cSJohn Marino
7517*ef5ccd6cSJohn Marino if (symbols == NULL)
7518*ef5ccd6cSJohn Marino return FALSE;
7519*ef5ccd6cSJohn Marino
7520*ef5ccd6cSJohn Marino cache = elf_tdata (abfd)->elf_find_function_cache;
7521*ef5ccd6cSJohn Marino if (cache == NULL)
7522*ef5ccd6cSJohn Marino {
7523*ef5ccd6cSJohn Marino cache = bfd_zalloc (abfd, sizeof (*cache));
7524*ef5ccd6cSJohn Marino elf_tdata (abfd)->elf_find_function_cache = cache;
7525*ef5ccd6cSJohn Marino if (cache == NULL)
7526*ef5ccd6cSJohn Marino return FALSE;
7527*ef5ccd6cSJohn Marino }
7528*ef5ccd6cSJohn Marino if (cache->last_section != section
7529*ef5ccd6cSJohn Marino || cache->func == NULL
7530*ef5ccd6cSJohn Marino || offset < cache->func->value
7531*ef5ccd6cSJohn Marino || offset >= cache->func->value + cache->func_size)
7532*ef5ccd6cSJohn Marino {
7533*ef5ccd6cSJohn Marino asymbol *file;
75345796c8dcSSimon Schubert bfd_vma low_func;
75355796c8dcSSimon Schubert asymbol **p;
75365796c8dcSSimon Schubert /* ??? Given multiple file symbols, it is impossible to reliably
75375796c8dcSSimon Schubert choose the right file name for global symbols. File symbols are
75385796c8dcSSimon Schubert local symbols, and thus all file symbols must sort before any
75395796c8dcSSimon Schubert global symbols. The ELF spec may be interpreted to say that a
75405796c8dcSSimon Schubert file symbol must sort before other local symbols, but currently
75415796c8dcSSimon Schubert ld -r doesn't do this. So, for ld -r output, it is possible to
75425796c8dcSSimon Schubert make a better choice of file name for local symbols by ignoring
75435796c8dcSSimon Schubert file symbols appearing after a given local symbol. */
75445796c8dcSSimon Schubert enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
75455796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
75465796c8dcSSimon Schubert
75475796c8dcSSimon Schubert file = NULL;
75485796c8dcSSimon Schubert low_func = 0;
75495796c8dcSSimon Schubert state = nothing_seen;
7550*ef5ccd6cSJohn Marino cache->filename = NULL;
7551*ef5ccd6cSJohn Marino cache->func = NULL;
7552*ef5ccd6cSJohn Marino cache->func_size = 0;
7553*ef5ccd6cSJohn Marino cache->last_section = section;
75545796c8dcSSimon Schubert
75555796c8dcSSimon Schubert for (p = symbols; *p != NULL; p++)
75565796c8dcSSimon Schubert {
7557*ef5ccd6cSJohn Marino asymbol *sym = *p;
7558*ef5ccd6cSJohn Marino bfd_vma code_off;
7559*ef5ccd6cSJohn Marino bfd_size_type size;
75605796c8dcSSimon Schubert
7561*ef5ccd6cSJohn Marino if ((sym->flags & BSF_FILE) != 0)
75625796c8dcSSimon Schubert {
7563*ef5ccd6cSJohn Marino file = sym;
75645796c8dcSSimon Schubert if (state == symbol_seen)
75655796c8dcSSimon Schubert state = file_after_symbol_seen;
75665796c8dcSSimon Schubert continue;
75675796c8dcSSimon Schubert }
7568*ef5ccd6cSJohn Marino
7569*ef5ccd6cSJohn Marino size = bed->maybe_function_sym (sym, section, &code_off);
7570*ef5ccd6cSJohn Marino if (size != 0
7571*ef5ccd6cSJohn Marino && code_off <= offset
7572*ef5ccd6cSJohn Marino && (code_off > low_func
7573*ef5ccd6cSJohn Marino || (code_off == low_func
7574*ef5ccd6cSJohn Marino && size > cache->func_size)))
7575*ef5ccd6cSJohn Marino {
7576*ef5ccd6cSJohn Marino cache->func = sym;
7577*ef5ccd6cSJohn Marino cache->func_size = size;
7578*ef5ccd6cSJohn Marino cache->filename = NULL;
7579*ef5ccd6cSJohn Marino low_func = code_off;
7580*ef5ccd6cSJohn Marino if (file != NULL
7581*ef5ccd6cSJohn Marino && ((sym->flags & BSF_LOCAL) != 0
7582*ef5ccd6cSJohn Marino || state != file_after_symbol_seen))
7583*ef5ccd6cSJohn Marino cache->filename = bfd_asymbol_name (file);
75845796c8dcSSimon Schubert }
75855796c8dcSSimon Schubert if (state == nothing_seen)
75865796c8dcSSimon Schubert state = symbol_seen;
75875796c8dcSSimon Schubert }
7588*ef5ccd6cSJohn Marino }
75895796c8dcSSimon Schubert
7590*ef5ccd6cSJohn Marino if (cache->func == NULL)
75915796c8dcSSimon Schubert return FALSE;
75925796c8dcSSimon Schubert
75935796c8dcSSimon Schubert if (filename_ptr)
7594*ef5ccd6cSJohn Marino *filename_ptr = cache->filename;
75955796c8dcSSimon Schubert if (functionname_ptr)
7596*ef5ccd6cSJohn Marino *functionname_ptr = bfd_asymbol_name (cache->func);
75975796c8dcSSimon Schubert
75985796c8dcSSimon Schubert return TRUE;
75995796c8dcSSimon Schubert }
76005796c8dcSSimon Schubert
76015796c8dcSSimon Schubert /* Find the nearest line to a particular section and offset,
76025796c8dcSSimon Schubert for error reporting. */
76035796c8dcSSimon Schubert
76045796c8dcSSimon Schubert bfd_boolean
_bfd_elf_find_nearest_line(bfd * abfd,asection * section,asymbol ** symbols,bfd_vma offset,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * line_ptr)76055796c8dcSSimon Schubert _bfd_elf_find_nearest_line (bfd *abfd,
76065796c8dcSSimon Schubert asection *section,
76075796c8dcSSimon Schubert asymbol **symbols,
76085796c8dcSSimon Schubert bfd_vma offset,
76095796c8dcSSimon Schubert const char **filename_ptr,
76105796c8dcSSimon Schubert const char **functionname_ptr,
76115796c8dcSSimon Schubert unsigned int *line_ptr)
76125796c8dcSSimon Schubert {
7613*ef5ccd6cSJohn Marino return _bfd_elf_find_nearest_line_discriminator (abfd, section, symbols,
7614*ef5ccd6cSJohn Marino offset, filename_ptr,
7615*ef5ccd6cSJohn Marino functionname_ptr,
7616*ef5ccd6cSJohn Marino line_ptr,
7617*ef5ccd6cSJohn Marino NULL);
7618*ef5ccd6cSJohn Marino }
7619*ef5ccd6cSJohn Marino
7620*ef5ccd6cSJohn Marino bfd_boolean
_bfd_elf_find_nearest_line_discriminator(bfd * abfd,asection * section,asymbol ** symbols,bfd_vma offset,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * line_ptr,unsigned int * discriminator_ptr)7621*ef5ccd6cSJohn Marino _bfd_elf_find_nearest_line_discriminator (bfd *abfd,
7622*ef5ccd6cSJohn Marino asection *section,
7623*ef5ccd6cSJohn Marino asymbol **symbols,
7624*ef5ccd6cSJohn Marino bfd_vma offset,
7625*ef5ccd6cSJohn Marino const char **filename_ptr,
7626*ef5ccd6cSJohn Marino const char **functionname_ptr,
7627*ef5ccd6cSJohn Marino unsigned int *line_ptr,
7628*ef5ccd6cSJohn Marino unsigned int *discriminator_ptr)
7629*ef5ccd6cSJohn Marino {
76305796c8dcSSimon Schubert bfd_boolean found;
76315796c8dcSSimon Schubert
76325796c8dcSSimon Schubert if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
76335796c8dcSSimon Schubert filename_ptr, functionname_ptr,
76345796c8dcSSimon Schubert line_ptr))
76355796c8dcSSimon Schubert {
76365796c8dcSSimon Schubert if (!*functionname_ptr)
76375796c8dcSSimon Schubert elf_find_function (abfd, section, symbols, offset,
76385796c8dcSSimon Schubert *filename_ptr ? NULL : filename_ptr,
76395796c8dcSSimon Schubert functionname_ptr);
76405796c8dcSSimon Schubert
76415796c8dcSSimon Schubert return TRUE;
76425796c8dcSSimon Schubert }
76435796c8dcSSimon Schubert
7644a45ae5f8SJohn Marino if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
7645a45ae5f8SJohn Marino section, symbols, offset,
76465796c8dcSSimon Schubert filename_ptr, functionname_ptr,
7647*ef5ccd6cSJohn Marino line_ptr, discriminator_ptr, 0,
76485796c8dcSSimon Schubert &elf_tdata (abfd)->dwarf2_find_line_info))
76495796c8dcSSimon Schubert {
76505796c8dcSSimon Schubert if (!*functionname_ptr)
76515796c8dcSSimon Schubert elf_find_function (abfd, section, symbols, offset,
76525796c8dcSSimon Schubert *filename_ptr ? NULL : filename_ptr,
76535796c8dcSSimon Schubert functionname_ptr);
76545796c8dcSSimon Schubert
76555796c8dcSSimon Schubert return TRUE;
76565796c8dcSSimon Schubert }
76575796c8dcSSimon Schubert
76585796c8dcSSimon Schubert if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
76595796c8dcSSimon Schubert &found, filename_ptr,
76605796c8dcSSimon Schubert functionname_ptr, line_ptr,
76615796c8dcSSimon Schubert &elf_tdata (abfd)->line_info))
76625796c8dcSSimon Schubert return FALSE;
76635796c8dcSSimon Schubert if (found && (*functionname_ptr || *line_ptr))
76645796c8dcSSimon Schubert return TRUE;
76655796c8dcSSimon Schubert
76665796c8dcSSimon Schubert if (symbols == NULL)
76675796c8dcSSimon Schubert return FALSE;
76685796c8dcSSimon Schubert
76695796c8dcSSimon Schubert if (! elf_find_function (abfd, section, symbols, offset,
76705796c8dcSSimon Schubert filename_ptr, functionname_ptr))
76715796c8dcSSimon Schubert return FALSE;
76725796c8dcSSimon Schubert
76735796c8dcSSimon Schubert *line_ptr = 0;
76745796c8dcSSimon Schubert return TRUE;
76755796c8dcSSimon Schubert }
76765796c8dcSSimon Schubert
76775796c8dcSSimon Schubert /* Find the line for a symbol. */
76785796c8dcSSimon Schubert
76795796c8dcSSimon Schubert bfd_boolean
_bfd_elf_find_line(bfd * abfd,asymbol ** symbols,asymbol * symbol,const char ** filename_ptr,unsigned int * line_ptr)76805796c8dcSSimon Schubert _bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
76815796c8dcSSimon Schubert const char **filename_ptr, unsigned int *line_ptr)
76825796c8dcSSimon Schubert {
7683*ef5ccd6cSJohn Marino return _bfd_elf_find_line_discriminator (abfd, symbols, symbol,
7684*ef5ccd6cSJohn Marino filename_ptr, line_ptr,
7685*ef5ccd6cSJohn Marino NULL);
7686*ef5ccd6cSJohn Marino }
7687*ef5ccd6cSJohn Marino
7688*ef5ccd6cSJohn Marino bfd_boolean
_bfd_elf_find_line_discriminator(bfd * abfd,asymbol ** symbols,asymbol * symbol,const char ** filename_ptr,unsigned int * line_ptr,unsigned int * discriminator_ptr)7689*ef5ccd6cSJohn Marino _bfd_elf_find_line_discriminator (bfd *abfd, asymbol **symbols, asymbol *symbol,
7690*ef5ccd6cSJohn Marino const char **filename_ptr,
7691*ef5ccd6cSJohn Marino unsigned int *line_ptr,
7692*ef5ccd6cSJohn Marino unsigned int *discriminator_ptr)
7693*ef5ccd6cSJohn Marino {
76945796c8dcSSimon Schubert return _bfd_dwarf2_find_line (abfd, symbols, symbol,
7695*ef5ccd6cSJohn Marino filename_ptr, line_ptr, discriminator_ptr, 0,
76965796c8dcSSimon Schubert &elf_tdata (abfd)->dwarf2_find_line_info);
76975796c8dcSSimon Schubert }
76985796c8dcSSimon Schubert
76995796c8dcSSimon Schubert /* After a call to bfd_find_nearest_line, successive calls to
77005796c8dcSSimon Schubert bfd_find_inliner_info can be used to get source information about
77015796c8dcSSimon Schubert each level of function inlining that terminated at the address
77025796c8dcSSimon Schubert passed to bfd_find_nearest_line. Currently this is only supported
77035796c8dcSSimon Schubert for DWARF2 with appropriate DWARF3 extensions. */
77045796c8dcSSimon Schubert
77055796c8dcSSimon Schubert bfd_boolean
_bfd_elf_find_inliner_info(bfd * abfd,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * line_ptr)77065796c8dcSSimon Schubert _bfd_elf_find_inliner_info (bfd *abfd,
77075796c8dcSSimon Schubert const char **filename_ptr,
77085796c8dcSSimon Schubert const char **functionname_ptr,
77095796c8dcSSimon Schubert unsigned int *line_ptr)
77105796c8dcSSimon Schubert {
77115796c8dcSSimon Schubert bfd_boolean found;
77125796c8dcSSimon Schubert found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
77135796c8dcSSimon Schubert functionname_ptr, line_ptr,
77145796c8dcSSimon Schubert & elf_tdata (abfd)->dwarf2_find_line_info);
77155796c8dcSSimon Schubert return found;
77165796c8dcSSimon Schubert }
77175796c8dcSSimon Schubert
77185796c8dcSSimon Schubert int
_bfd_elf_sizeof_headers(bfd * abfd,struct bfd_link_info * info)77195796c8dcSSimon Schubert _bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
77205796c8dcSSimon Schubert {
77215796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
77225796c8dcSSimon Schubert int ret = bed->s->sizeof_ehdr;
77235796c8dcSSimon Schubert
77245796c8dcSSimon Schubert if (!info->relocatable)
77255796c8dcSSimon Schubert {
7726*ef5ccd6cSJohn Marino bfd_size_type phdr_size = elf_program_header_size (abfd);
77275796c8dcSSimon Schubert
77285796c8dcSSimon Schubert if (phdr_size == (bfd_size_type) -1)
77295796c8dcSSimon Schubert {
77305796c8dcSSimon Schubert struct elf_segment_map *m;
77315796c8dcSSimon Schubert
77325796c8dcSSimon Schubert phdr_size = 0;
7733*ef5ccd6cSJohn Marino for (m = elf_seg_map (abfd); m != NULL; m = m->next)
77345796c8dcSSimon Schubert phdr_size += bed->s->sizeof_phdr;
77355796c8dcSSimon Schubert
77365796c8dcSSimon Schubert if (phdr_size == 0)
77375796c8dcSSimon Schubert phdr_size = get_program_header_size (abfd, info);
77385796c8dcSSimon Schubert }
77395796c8dcSSimon Schubert
7740*ef5ccd6cSJohn Marino elf_program_header_size (abfd) = phdr_size;
77415796c8dcSSimon Schubert ret += phdr_size;
77425796c8dcSSimon Schubert }
77435796c8dcSSimon Schubert
77445796c8dcSSimon Schubert return ret;
77455796c8dcSSimon Schubert }
77465796c8dcSSimon Schubert
77475796c8dcSSimon Schubert bfd_boolean
_bfd_elf_set_section_contents(bfd * abfd,sec_ptr section,const void * location,file_ptr offset,bfd_size_type count)77485796c8dcSSimon Schubert _bfd_elf_set_section_contents (bfd *abfd,
77495796c8dcSSimon Schubert sec_ptr section,
77505796c8dcSSimon Schubert const void *location,
77515796c8dcSSimon Schubert file_ptr offset,
77525796c8dcSSimon Schubert bfd_size_type count)
77535796c8dcSSimon Schubert {
77545796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
77555796c8dcSSimon Schubert bfd_signed_vma pos;
77565796c8dcSSimon Schubert
77575796c8dcSSimon Schubert if (! abfd->output_has_begun
77585796c8dcSSimon Schubert && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
77595796c8dcSSimon Schubert return FALSE;
77605796c8dcSSimon Schubert
77615796c8dcSSimon Schubert hdr = &elf_section_data (section)->this_hdr;
77625796c8dcSSimon Schubert pos = hdr->sh_offset + offset;
77635796c8dcSSimon Schubert if (bfd_seek (abfd, pos, SEEK_SET) != 0
77645796c8dcSSimon Schubert || bfd_bwrite (location, count, abfd) != count)
77655796c8dcSSimon Schubert return FALSE;
77665796c8dcSSimon Schubert
77675796c8dcSSimon Schubert return TRUE;
77685796c8dcSSimon Schubert }
77695796c8dcSSimon Schubert
77705796c8dcSSimon Schubert void
_bfd_elf_no_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr ATTRIBUTE_UNUSED,Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)77715796c8dcSSimon Schubert _bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
77725796c8dcSSimon Schubert arelent *cache_ptr ATTRIBUTE_UNUSED,
77735796c8dcSSimon Schubert Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
77745796c8dcSSimon Schubert {
77755796c8dcSSimon Schubert abort ();
77765796c8dcSSimon Schubert }
77775796c8dcSSimon Schubert
77785796c8dcSSimon Schubert /* Try to convert a non-ELF reloc into an ELF one. */
77795796c8dcSSimon Schubert
77805796c8dcSSimon Schubert bfd_boolean
_bfd_elf_validate_reloc(bfd * abfd,arelent * areloc)77815796c8dcSSimon Schubert _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
77825796c8dcSSimon Schubert {
77835796c8dcSSimon Schubert /* Check whether we really have an ELF howto. */
77845796c8dcSSimon Schubert
77855796c8dcSSimon Schubert if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
77865796c8dcSSimon Schubert {
77875796c8dcSSimon Schubert bfd_reloc_code_real_type code;
77885796c8dcSSimon Schubert reloc_howto_type *howto;
77895796c8dcSSimon Schubert
77905796c8dcSSimon Schubert /* Alien reloc: Try to determine its type to replace it with an
77915796c8dcSSimon Schubert equivalent ELF reloc. */
77925796c8dcSSimon Schubert
77935796c8dcSSimon Schubert if (areloc->howto->pc_relative)
77945796c8dcSSimon Schubert {
77955796c8dcSSimon Schubert switch (areloc->howto->bitsize)
77965796c8dcSSimon Schubert {
77975796c8dcSSimon Schubert case 8:
77985796c8dcSSimon Schubert code = BFD_RELOC_8_PCREL;
77995796c8dcSSimon Schubert break;
78005796c8dcSSimon Schubert case 12:
78015796c8dcSSimon Schubert code = BFD_RELOC_12_PCREL;
78025796c8dcSSimon Schubert break;
78035796c8dcSSimon Schubert case 16:
78045796c8dcSSimon Schubert code = BFD_RELOC_16_PCREL;
78055796c8dcSSimon Schubert break;
78065796c8dcSSimon Schubert case 24:
78075796c8dcSSimon Schubert code = BFD_RELOC_24_PCREL;
78085796c8dcSSimon Schubert break;
78095796c8dcSSimon Schubert case 32:
78105796c8dcSSimon Schubert code = BFD_RELOC_32_PCREL;
78115796c8dcSSimon Schubert break;
78125796c8dcSSimon Schubert case 64:
78135796c8dcSSimon Schubert code = BFD_RELOC_64_PCREL;
78145796c8dcSSimon Schubert break;
78155796c8dcSSimon Schubert default:
78165796c8dcSSimon Schubert goto fail;
78175796c8dcSSimon Schubert }
78185796c8dcSSimon Schubert
78195796c8dcSSimon Schubert howto = bfd_reloc_type_lookup (abfd, code);
78205796c8dcSSimon Schubert
78215796c8dcSSimon Schubert if (areloc->howto->pcrel_offset != howto->pcrel_offset)
78225796c8dcSSimon Schubert {
78235796c8dcSSimon Schubert if (howto->pcrel_offset)
78245796c8dcSSimon Schubert areloc->addend += areloc->address;
78255796c8dcSSimon Schubert else
78265796c8dcSSimon Schubert areloc->addend -= areloc->address; /* addend is unsigned!! */
78275796c8dcSSimon Schubert }
78285796c8dcSSimon Schubert }
78295796c8dcSSimon Schubert else
78305796c8dcSSimon Schubert {
78315796c8dcSSimon Schubert switch (areloc->howto->bitsize)
78325796c8dcSSimon Schubert {
78335796c8dcSSimon Schubert case 8:
78345796c8dcSSimon Schubert code = BFD_RELOC_8;
78355796c8dcSSimon Schubert break;
78365796c8dcSSimon Schubert case 14:
78375796c8dcSSimon Schubert code = BFD_RELOC_14;
78385796c8dcSSimon Schubert break;
78395796c8dcSSimon Schubert case 16:
78405796c8dcSSimon Schubert code = BFD_RELOC_16;
78415796c8dcSSimon Schubert break;
78425796c8dcSSimon Schubert case 26:
78435796c8dcSSimon Schubert code = BFD_RELOC_26;
78445796c8dcSSimon Schubert break;
78455796c8dcSSimon Schubert case 32:
78465796c8dcSSimon Schubert code = BFD_RELOC_32;
78475796c8dcSSimon Schubert break;
78485796c8dcSSimon Schubert case 64:
78495796c8dcSSimon Schubert code = BFD_RELOC_64;
78505796c8dcSSimon Schubert break;
78515796c8dcSSimon Schubert default:
78525796c8dcSSimon Schubert goto fail;
78535796c8dcSSimon Schubert }
78545796c8dcSSimon Schubert
78555796c8dcSSimon Schubert howto = bfd_reloc_type_lookup (abfd, code);
78565796c8dcSSimon Schubert }
78575796c8dcSSimon Schubert
78585796c8dcSSimon Schubert if (howto)
78595796c8dcSSimon Schubert areloc->howto = howto;
78605796c8dcSSimon Schubert else
78615796c8dcSSimon Schubert goto fail;
78625796c8dcSSimon Schubert }
78635796c8dcSSimon Schubert
78645796c8dcSSimon Schubert return TRUE;
78655796c8dcSSimon Schubert
78665796c8dcSSimon Schubert fail:
78675796c8dcSSimon Schubert (*_bfd_error_handler)
78685796c8dcSSimon Schubert (_("%B: unsupported relocation type %s"),
78695796c8dcSSimon Schubert abfd, areloc->howto->name);
78705796c8dcSSimon Schubert bfd_set_error (bfd_error_bad_value);
78715796c8dcSSimon Schubert return FALSE;
78725796c8dcSSimon Schubert }
78735796c8dcSSimon Schubert
78745796c8dcSSimon Schubert bfd_boolean
_bfd_elf_close_and_cleanup(bfd * abfd)78755796c8dcSSimon Schubert _bfd_elf_close_and_cleanup (bfd *abfd)
78765796c8dcSSimon Schubert {
7877*ef5ccd6cSJohn Marino struct elf_obj_tdata *tdata = elf_tdata (abfd);
7878*ef5ccd6cSJohn Marino if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
78795796c8dcSSimon Schubert {
7880*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
78815796c8dcSSimon Schubert _bfd_elf_strtab_free (elf_shstrtab (abfd));
7882*ef5ccd6cSJohn Marino _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
78835796c8dcSSimon Schubert }
78845796c8dcSSimon Schubert
78855796c8dcSSimon Schubert return _bfd_generic_close_and_cleanup (abfd);
78865796c8dcSSimon Schubert }
78875796c8dcSSimon Schubert
78885796c8dcSSimon Schubert /* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY
78895796c8dcSSimon Schubert in the relocation's offset. Thus we cannot allow any sort of sanity
78905796c8dcSSimon Schubert range-checking to interfere. There is nothing else to do in processing
78915796c8dcSSimon Schubert this reloc. */
78925796c8dcSSimon Schubert
78935796c8dcSSimon Schubert bfd_reloc_status_type
_bfd_elf_rel_vtable_reloc_fn(bfd * abfd ATTRIBUTE_UNUSED,arelent * re ATTRIBUTE_UNUSED,struct bfd_symbol * symbol ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED,asection * is ATTRIBUTE_UNUSED,bfd * obfd ATTRIBUTE_UNUSED,char ** errmsg ATTRIBUTE_UNUSED)78945796c8dcSSimon Schubert _bfd_elf_rel_vtable_reloc_fn
78955796c8dcSSimon Schubert (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
78965796c8dcSSimon Schubert struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
78975796c8dcSSimon Schubert void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
78985796c8dcSSimon Schubert bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
78995796c8dcSSimon Schubert {
79005796c8dcSSimon Schubert return bfd_reloc_ok;
79015796c8dcSSimon Schubert }
79025796c8dcSSimon Schubert
79035796c8dcSSimon Schubert /* Elf core file support. Much of this only works on native
79045796c8dcSSimon Schubert toolchains, since we rely on knowing the
79055796c8dcSSimon Schubert machine-dependent procfs structure in order to pick
79065796c8dcSSimon Schubert out details about the corefile. */
79075796c8dcSSimon Schubert
79085796c8dcSSimon Schubert #ifdef HAVE_SYS_PROCFS_H
7909cf7f2e2dSJohn Marino /* Needed for new procfs interface on sparc-solaris. */
7910cf7f2e2dSJohn Marino # define _STRUCTURED_PROC 1
79115796c8dcSSimon Schubert # include <sys/procfs.h>
79125796c8dcSSimon Schubert #endif
79135796c8dcSSimon Schubert
7914c50c785cSJohn Marino /* Return a PID that identifies a "thread" for threaded cores, or the
7915c50c785cSJohn Marino PID of the main process for non-threaded cores. */
79165796c8dcSSimon Schubert
79175796c8dcSSimon Schubert static int
elfcore_make_pid(bfd * abfd)79185796c8dcSSimon Schubert elfcore_make_pid (bfd *abfd)
79195796c8dcSSimon Schubert {
7920c50c785cSJohn Marino int pid;
7921c50c785cSJohn Marino
7922*ef5ccd6cSJohn Marino pid = elf_tdata (abfd)->core->lwpid;
7923c50c785cSJohn Marino if (pid == 0)
7924*ef5ccd6cSJohn Marino pid = elf_tdata (abfd)->core->pid;
7925c50c785cSJohn Marino
7926c50c785cSJohn Marino return pid;
79275796c8dcSSimon Schubert }
79285796c8dcSSimon Schubert
79295796c8dcSSimon Schubert /* If there isn't a section called NAME, make one, using
79305796c8dcSSimon Schubert data from SECT. Note, this function will generate a
79315796c8dcSSimon Schubert reference to NAME, so you shouldn't deallocate or
79325796c8dcSSimon Schubert overwrite it. */
79335796c8dcSSimon Schubert
79345796c8dcSSimon Schubert static bfd_boolean
elfcore_maybe_make_sect(bfd * abfd,char * name,asection * sect)79355796c8dcSSimon Schubert elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
79365796c8dcSSimon Schubert {
79375796c8dcSSimon Schubert asection *sect2;
79385796c8dcSSimon Schubert
79395796c8dcSSimon Schubert if (bfd_get_section_by_name (abfd, name) != NULL)
79405796c8dcSSimon Schubert return TRUE;
79415796c8dcSSimon Schubert
79425796c8dcSSimon Schubert sect2 = bfd_make_section_with_flags (abfd, name, sect->flags);
79435796c8dcSSimon Schubert if (sect2 == NULL)
79445796c8dcSSimon Schubert return FALSE;
79455796c8dcSSimon Schubert
79465796c8dcSSimon Schubert sect2->size = sect->size;
79475796c8dcSSimon Schubert sect2->filepos = sect->filepos;
79485796c8dcSSimon Schubert sect2->alignment_power = sect->alignment_power;
79495796c8dcSSimon Schubert return TRUE;
79505796c8dcSSimon Schubert }
79515796c8dcSSimon Schubert
79525796c8dcSSimon Schubert /* Create a pseudosection containing SIZE bytes at FILEPOS. This
79535796c8dcSSimon Schubert actually creates up to two pseudosections:
79545796c8dcSSimon Schubert - For the single-threaded case, a section named NAME, unless
79555796c8dcSSimon Schubert such a section already exists.
79565796c8dcSSimon Schubert - For the multi-threaded case, a section named "NAME/PID", where
79575796c8dcSSimon Schubert PID is elfcore_make_pid (abfd).
79585796c8dcSSimon Schubert Both pseudosections have identical contents. */
79595796c8dcSSimon Schubert bfd_boolean
_bfd_elfcore_make_pseudosection(bfd * abfd,char * name,size_t size,ufile_ptr filepos)79605796c8dcSSimon Schubert _bfd_elfcore_make_pseudosection (bfd *abfd,
79615796c8dcSSimon Schubert char *name,
79625796c8dcSSimon Schubert size_t size,
79635796c8dcSSimon Schubert ufile_ptr filepos)
79645796c8dcSSimon Schubert {
79655796c8dcSSimon Schubert char buf[100];
79665796c8dcSSimon Schubert char *threaded_name;
79675796c8dcSSimon Schubert size_t len;
79685796c8dcSSimon Schubert asection *sect;
79695796c8dcSSimon Schubert
79705796c8dcSSimon Schubert /* Build the section name. */
79715796c8dcSSimon Schubert
79725796c8dcSSimon Schubert sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
79735796c8dcSSimon Schubert len = strlen (buf) + 1;
79745796c8dcSSimon Schubert threaded_name = (char *) bfd_alloc (abfd, len);
79755796c8dcSSimon Schubert if (threaded_name == NULL)
79765796c8dcSSimon Schubert return FALSE;
79775796c8dcSSimon Schubert memcpy (threaded_name, buf, len);
79785796c8dcSSimon Schubert
79795796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
79805796c8dcSSimon Schubert SEC_HAS_CONTENTS);
79815796c8dcSSimon Schubert if (sect == NULL)
79825796c8dcSSimon Schubert return FALSE;
79835796c8dcSSimon Schubert sect->size = size;
79845796c8dcSSimon Schubert sect->filepos = filepos;
79855796c8dcSSimon Schubert sect->alignment_power = 2;
79865796c8dcSSimon Schubert
79875796c8dcSSimon Schubert return elfcore_maybe_make_sect (abfd, name, sect);
79885796c8dcSSimon Schubert }
79895796c8dcSSimon Schubert
79905796c8dcSSimon Schubert /* prstatus_t exists on:
79915796c8dcSSimon Schubert solaris 2.5+
79925796c8dcSSimon Schubert linux 2.[01] + glibc
79935796c8dcSSimon Schubert unixware 4.2
79945796c8dcSSimon Schubert */
79955796c8dcSSimon Schubert
79965796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS_T)
79975796c8dcSSimon Schubert
79985796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)79995796c8dcSSimon Schubert elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
80005796c8dcSSimon Schubert {
80015796c8dcSSimon Schubert size_t size;
80025796c8dcSSimon Schubert int offset;
80035796c8dcSSimon Schubert
80045796c8dcSSimon Schubert if (note->descsz == sizeof (prstatus_t))
80055796c8dcSSimon Schubert {
80065796c8dcSSimon Schubert prstatus_t prstat;
80075796c8dcSSimon Schubert
80085796c8dcSSimon Schubert size = sizeof (prstat.pr_reg);
80095796c8dcSSimon Schubert offset = offsetof (prstatus_t, pr_reg);
80105796c8dcSSimon Schubert memcpy (&prstat, note->descdata, sizeof (prstat));
80115796c8dcSSimon Schubert
80125796c8dcSSimon Schubert /* Do not overwrite the core signal if it
80135796c8dcSSimon Schubert has already been set by another thread. */
8014*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->core->signal == 0)
8015*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal = prstat.pr_cursig;
8016*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->core->pid == 0)
8017*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = prstat.pr_pid;
80185796c8dcSSimon Schubert
80195796c8dcSSimon Schubert /* pr_who exists on:
80205796c8dcSSimon Schubert solaris 2.5+
80215796c8dcSSimon Schubert unixware 4.2
80225796c8dcSSimon Schubert pr_who doesn't exist on:
80235796c8dcSSimon Schubert linux 2.[01]
80245796c8dcSSimon Schubert */
80255796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS_T_PR_WHO)
8026*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = prstat.pr_who;
8027c50c785cSJohn Marino #else
8028*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
80295796c8dcSSimon Schubert #endif
80305796c8dcSSimon Schubert }
80315796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS32_T)
80325796c8dcSSimon Schubert else if (note->descsz == sizeof (prstatus32_t))
80335796c8dcSSimon Schubert {
80345796c8dcSSimon Schubert /* 64-bit host, 32-bit corefile */
80355796c8dcSSimon Schubert prstatus32_t prstat;
80365796c8dcSSimon Schubert
80375796c8dcSSimon Schubert size = sizeof (prstat.pr_reg);
80385796c8dcSSimon Schubert offset = offsetof (prstatus32_t, pr_reg);
80395796c8dcSSimon Schubert memcpy (&prstat, note->descdata, sizeof (prstat));
80405796c8dcSSimon Schubert
80415796c8dcSSimon Schubert /* Do not overwrite the core signal if it
80425796c8dcSSimon Schubert has already been set by another thread. */
8043*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->core->signal == 0)
8044*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal = prstat.pr_cursig;
8045*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->core->pid == 0)
8046*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = prstat.pr_pid;
80475796c8dcSSimon Schubert
80485796c8dcSSimon Schubert /* pr_who exists on:
80495796c8dcSSimon Schubert solaris 2.5+
80505796c8dcSSimon Schubert unixware 4.2
80515796c8dcSSimon Schubert pr_who doesn't exist on:
80525796c8dcSSimon Schubert linux 2.[01]
80535796c8dcSSimon Schubert */
80545796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS32_T_PR_WHO)
8055*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = prstat.pr_who;
8056c50c785cSJohn Marino #else
8057*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
80585796c8dcSSimon Schubert #endif
80595796c8dcSSimon Schubert }
80605796c8dcSSimon Schubert #endif /* HAVE_PRSTATUS32_T */
80615796c8dcSSimon Schubert else
80625796c8dcSSimon Schubert {
80635796c8dcSSimon Schubert /* Fail - we don't know how to handle any other
80645796c8dcSSimon Schubert note size (ie. data object type). */
80655796c8dcSSimon Schubert return TRUE;
80665796c8dcSSimon Schubert }
80675796c8dcSSimon Schubert
80685796c8dcSSimon Schubert /* Make a ".reg/999" section and a ".reg" section. */
80695796c8dcSSimon Schubert return _bfd_elfcore_make_pseudosection (abfd, ".reg",
80705796c8dcSSimon Schubert size, note->descpos + offset);
80715796c8dcSSimon Schubert }
80725796c8dcSSimon Schubert #endif /* defined (HAVE_PRSTATUS_T) */
80735796c8dcSSimon Schubert
80745796c8dcSSimon Schubert /* Create a pseudosection containing the exact contents of NOTE. */
80755796c8dcSSimon Schubert static bfd_boolean
elfcore_make_note_pseudosection(bfd * abfd,char * name,Elf_Internal_Note * note)80765796c8dcSSimon Schubert elfcore_make_note_pseudosection (bfd *abfd,
80775796c8dcSSimon Schubert char *name,
80785796c8dcSSimon Schubert Elf_Internal_Note *note)
80795796c8dcSSimon Schubert {
80805796c8dcSSimon Schubert return _bfd_elfcore_make_pseudosection (abfd, name,
80815796c8dcSSimon Schubert note->descsz, note->descpos);
80825796c8dcSSimon Schubert }
80835796c8dcSSimon Schubert
80845796c8dcSSimon Schubert /* There isn't a consistent prfpregset_t across platforms,
80855796c8dcSSimon Schubert but it doesn't matter, because we don't have to pick this
80865796c8dcSSimon Schubert data structure apart. */
80875796c8dcSSimon Schubert
80885796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_prfpreg(bfd * abfd,Elf_Internal_Note * note)80895796c8dcSSimon Schubert elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
80905796c8dcSSimon Schubert {
80915796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg2", note);
80925796c8dcSSimon Schubert }
80935796c8dcSSimon Schubert
80945796c8dcSSimon Schubert /* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
80955796c8dcSSimon Schubert type of NT_PRXFPREG. Just include the whole note's contents
80965796c8dcSSimon Schubert literally. */
80975796c8dcSSimon Schubert
80985796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_prxfpreg(bfd * abfd,Elf_Internal_Note * note)80995796c8dcSSimon Schubert elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
81005796c8dcSSimon Schubert {
81015796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
81025796c8dcSSimon Schubert }
81035796c8dcSSimon Schubert
8104cf7f2e2dSJohn Marino /* Linux dumps the Intel XSAVE extended state in a note named "LINUX"
8105cf7f2e2dSJohn Marino with a note type of NT_X86_XSTATE. Just include the whole note's
8106cf7f2e2dSJohn Marino contents literally. */
8107cf7f2e2dSJohn Marino
8108cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_xstatereg(bfd * abfd,Elf_Internal_Note * note)8109cf7f2e2dSJohn Marino elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note)
8110cf7f2e2dSJohn Marino {
8111cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note);
8112cf7f2e2dSJohn Marino }
8113cf7f2e2dSJohn Marino
81145796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_ppc_vmx(bfd * abfd,Elf_Internal_Note * note)81155796c8dcSSimon Schubert elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
81165796c8dcSSimon Schubert {
81175796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
81185796c8dcSSimon Schubert }
81195796c8dcSSimon Schubert
81205796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_ppc_vsx(bfd * abfd,Elf_Internal_Note * note)81215796c8dcSSimon Schubert elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
81225796c8dcSSimon Schubert {
81235796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note);
81245796c8dcSSimon Schubert }
81255796c8dcSSimon Schubert
8126cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_high_gprs(bfd * abfd,Elf_Internal_Note * note)8127cf7f2e2dSJohn Marino elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note)
8128cf7f2e2dSJohn Marino {
8129cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note);
8130cf7f2e2dSJohn Marino }
8131cf7f2e2dSJohn Marino
8132cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_timer(bfd * abfd,Elf_Internal_Note * note)8133cf7f2e2dSJohn Marino elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
8134cf7f2e2dSJohn Marino {
8135cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note);
8136cf7f2e2dSJohn Marino }
8137cf7f2e2dSJohn Marino
8138cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_todcmp(bfd * abfd,Elf_Internal_Note * note)8139cf7f2e2dSJohn Marino elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
8140cf7f2e2dSJohn Marino {
8141cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note);
8142cf7f2e2dSJohn Marino }
8143cf7f2e2dSJohn Marino
8144cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_todpreg(bfd * abfd,Elf_Internal_Note * note)8145cf7f2e2dSJohn Marino elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
8146cf7f2e2dSJohn Marino {
8147cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note);
8148cf7f2e2dSJohn Marino }
8149cf7f2e2dSJohn Marino
8150cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_ctrs(bfd * abfd,Elf_Internal_Note * note)8151cf7f2e2dSJohn Marino elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
8152cf7f2e2dSJohn Marino {
8153cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note);
8154cf7f2e2dSJohn Marino }
8155cf7f2e2dSJohn Marino
8156cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_prefix(bfd * abfd,Elf_Internal_Note * note)8157cf7f2e2dSJohn Marino elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
8158cf7f2e2dSJohn Marino {
8159cf7f2e2dSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
8160cf7f2e2dSJohn Marino }
8161cf7f2e2dSJohn Marino
8162a45ae5f8SJohn Marino static bfd_boolean
elfcore_grok_s390_last_break(bfd * abfd,Elf_Internal_Note * note)8163a45ae5f8SJohn Marino elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
8164a45ae5f8SJohn Marino {
8165a45ae5f8SJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
8166a45ae5f8SJohn Marino }
8167a45ae5f8SJohn Marino
8168a45ae5f8SJohn Marino static bfd_boolean
elfcore_grok_s390_system_call(bfd * abfd,Elf_Internal_Note * note)8169a45ae5f8SJohn Marino elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
8170a45ae5f8SJohn Marino {
8171a45ae5f8SJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
8172a45ae5f8SJohn Marino }
8173a45ae5f8SJohn Marino
8174a45ae5f8SJohn Marino static bfd_boolean
elfcore_grok_s390_tdb(bfd * abfd,Elf_Internal_Note * note)8175*ef5ccd6cSJohn Marino elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
8176*ef5ccd6cSJohn Marino {
8177*ef5ccd6cSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
8178*ef5ccd6cSJohn Marino }
8179*ef5ccd6cSJohn Marino
8180*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_arm_vfp(bfd * abfd,Elf_Internal_Note * note)8181a45ae5f8SJohn Marino elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
8182a45ae5f8SJohn Marino {
8183a45ae5f8SJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
8184a45ae5f8SJohn Marino }
8185a45ae5f8SJohn Marino
8186*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_aarch_tls(bfd * abfd,Elf_Internal_Note * note)8187*ef5ccd6cSJohn Marino elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
8188*ef5ccd6cSJohn Marino {
8189*ef5ccd6cSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note);
8190*ef5ccd6cSJohn Marino }
8191*ef5ccd6cSJohn Marino
8192*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_aarch_hw_break(bfd * abfd,Elf_Internal_Note * note)8193*ef5ccd6cSJohn Marino elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
8194*ef5ccd6cSJohn Marino {
8195*ef5ccd6cSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note);
8196*ef5ccd6cSJohn Marino }
8197*ef5ccd6cSJohn Marino
8198*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_aarch_hw_watch(bfd * abfd,Elf_Internal_Note * note)8199*ef5ccd6cSJohn Marino elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
8200*ef5ccd6cSJohn Marino {
8201*ef5ccd6cSJohn Marino return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note);
8202*ef5ccd6cSJohn Marino }
8203*ef5ccd6cSJohn Marino
82045796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO_T)
82055796c8dcSSimon Schubert typedef prpsinfo_t elfcore_psinfo_t;
82065796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */
82075796c8dcSSimon Schubert typedef prpsinfo32_t elfcore_psinfo32_t;
82085796c8dcSSimon Schubert #endif
82095796c8dcSSimon Schubert #endif
82105796c8dcSSimon Schubert
82115796c8dcSSimon Schubert #if defined (HAVE_PSINFO_T)
82125796c8dcSSimon Schubert typedef psinfo_t elfcore_psinfo_t;
82135796c8dcSSimon Schubert #if defined (HAVE_PSINFO32_T) /* Sparc64 cross Sparc32 */
82145796c8dcSSimon Schubert typedef psinfo32_t elfcore_psinfo32_t;
82155796c8dcSSimon Schubert #endif
82165796c8dcSSimon Schubert #endif
82175796c8dcSSimon Schubert
82185796c8dcSSimon Schubert /* return a malloc'ed copy of a string at START which is at
82195796c8dcSSimon Schubert most MAX bytes long, possibly without a terminating '\0'.
82205796c8dcSSimon Schubert the copy will always have a terminating '\0'. */
82215796c8dcSSimon Schubert
82225796c8dcSSimon Schubert char *
_bfd_elfcore_strndup(bfd * abfd,char * start,size_t max)82235796c8dcSSimon Schubert _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
82245796c8dcSSimon Schubert {
82255796c8dcSSimon Schubert char *dups;
82265796c8dcSSimon Schubert char *end = (char *) memchr (start, '\0', max);
82275796c8dcSSimon Schubert size_t len;
82285796c8dcSSimon Schubert
82295796c8dcSSimon Schubert if (end == NULL)
82305796c8dcSSimon Schubert len = max;
82315796c8dcSSimon Schubert else
82325796c8dcSSimon Schubert len = end - start;
82335796c8dcSSimon Schubert
82345796c8dcSSimon Schubert dups = (char *) bfd_alloc (abfd, len + 1);
82355796c8dcSSimon Schubert if (dups == NULL)
82365796c8dcSSimon Schubert return NULL;
82375796c8dcSSimon Schubert
82385796c8dcSSimon Schubert memcpy (dups, start, len);
82395796c8dcSSimon Schubert dups[len] = '\0';
82405796c8dcSSimon Schubert
82415796c8dcSSimon Schubert return dups;
82425796c8dcSSimon Schubert }
82435796c8dcSSimon Schubert
82445796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
82455796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)82465796c8dcSSimon Schubert elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
82475796c8dcSSimon Schubert {
82485796c8dcSSimon Schubert if (note->descsz == sizeof (elfcore_psinfo_t))
82495796c8dcSSimon Schubert {
82505796c8dcSSimon Schubert elfcore_psinfo_t psinfo;
82515796c8dcSSimon Schubert
82525796c8dcSSimon Schubert memcpy (&psinfo, note->descdata, sizeof (psinfo));
82535796c8dcSSimon Schubert
8254a45ae5f8SJohn Marino #if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
8255*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = psinfo.pr_pid;
8256a45ae5f8SJohn Marino #endif
8257*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->program
82585796c8dcSSimon Schubert = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
82595796c8dcSSimon Schubert sizeof (psinfo.pr_fname));
82605796c8dcSSimon Schubert
8261*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->command
82625796c8dcSSimon Schubert = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
82635796c8dcSSimon Schubert sizeof (psinfo.pr_psargs));
82645796c8dcSSimon Schubert }
82655796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
82665796c8dcSSimon Schubert else if (note->descsz == sizeof (elfcore_psinfo32_t))
82675796c8dcSSimon Schubert {
82685796c8dcSSimon Schubert /* 64-bit host, 32-bit corefile */
82695796c8dcSSimon Schubert elfcore_psinfo32_t psinfo;
82705796c8dcSSimon Schubert
82715796c8dcSSimon Schubert memcpy (&psinfo, note->descdata, sizeof (psinfo));
82725796c8dcSSimon Schubert
8273a45ae5f8SJohn Marino #if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
8274*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = psinfo.pr_pid;
8275a45ae5f8SJohn Marino #endif
8276*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->program
82775796c8dcSSimon Schubert = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
82785796c8dcSSimon Schubert sizeof (psinfo.pr_fname));
82795796c8dcSSimon Schubert
8280*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->command
82815796c8dcSSimon Schubert = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
82825796c8dcSSimon Schubert sizeof (psinfo.pr_psargs));
82835796c8dcSSimon Schubert }
82845796c8dcSSimon Schubert #endif
82855796c8dcSSimon Schubert
82865796c8dcSSimon Schubert else
82875796c8dcSSimon Schubert {
82885796c8dcSSimon Schubert /* Fail - we don't know how to handle any other
82895796c8dcSSimon Schubert note size (ie. data object type). */
82905796c8dcSSimon Schubert return TRUE;
82915796c8dcSSimon Schubert }
82925796c8dcSSimon Schubert
82935796c8dcSSimon Schubert /* Note that for some reason, a spurious space is tacked
82945796c8dcSSimon Schubert onto the end of the args in some (at least one anyway)
82955796c8dcSSimon Schubert implementations, so strip it off if it exists. */
82965796c8dcSSimon Schubert
82975796c8dcSSimon Schubert {
8298*ef5ccd6cSJohn Marino char *command = elf_tdata (abfd)->core->command;
82995796c8dcSSimon Schubert int n = strlen (command);
83005796c8dcSSimon Schubert
83015796c8dcSSimon Schubert if (0 < n && command[n - 1] == ' ')
83025796c8dcSSimon Schubert command[n - 1] = '\0';
83035796c8dcSSimon Schubert }
83045796c8dcSSimon Schubert
83055796c8dcSSimon Schubert return TRUE;
83065796c8dcSSimon Schubert }
83075796c8dcSSimon Schubert #endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
83085796c8dcSSimon Schubert
83095796c8dcSSimon Schubert #if defined (HAVE_PSTATUS_T)
83105796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_pstatus(bfd * abfd,Elf_Internal_Note * note)83115796c8dcSSimon Schubert elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
83125796c8dcSSimon Schubert {
83135796c8dcSSimon Schubert if (note->descsz == sizeof (pstatus_t)
83145796c8dcSSimon Schubert #if defined (HAVE_PXSTATUS_T)
83155796c8dcSSimon Schubert || note->descsz == sizeof (pxstatus_t)
83165796c8dcSSimon Schubert #endif
83175796c8dcSSimon Schubert )
83185796c8dcSSimon Schubert {
83195796c8dcSSimon Schubert pstatus_t pstat;
83205796c8dcSSimon Schubert
83215796c8dcSSimon Schubert memcpy (&pstat, note->descdata, sizeof (pstat));
83225796c8dcSSimon Schubert
8323*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = pstat.pr_pid;
83245796c8dcSSimon Schubert }
83255796c8dcSSimon Schubert #if defined (HAVE_PSTATUS32_T)
83265796c8dcSSimon Schubert else if (note->descsz == sizeof (pstatus32_t))
83275796c8dcSSimon Schubert {
83285796c8dcSSimon Schubert /* 64-bit host, 32-bit corefile */
83295796c8dcSSimon Schubert pstatus32_t pstat;
83305796c8dcSSimon Schubert
83315796c8dcSSimon Schubert memcpy (&pstat, note->descdata, sizeof (pstat));
83325796c8dcSSimon Schubert
8333*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = pstat.pr_pid;
83345796c8dcSSimon Schubert }
83355796c8dcSSimon Schubert #endif
83365796c8dcSSimon Schubert /* Could grab some more details from the "representative"
83375796c8dcSSimon Schubert lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
83385796c8dcSSimon Schubert NT_LWPSTATUS note, presumably. */
83395796c8dcSSimon Schubert
83405796c8dcSSimon Schubert return TRUE;
83415796c8dcSSimon Schubert }
83425796c8dcSSimon Schubert #endif /* defined (HAVE_PSTATUS_T) */
83435796c8dcSSimon Schubert
83445796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T)
83455796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_lwpstatus(bfd * abfd,Elf_Internal_Note * note)83465796c8dcSSimon Schubert elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
83475796c8dcSSimon Schubert {
83485796c8dcSSimon Schubert lwpstatus_t lwpstat;
83495796c8dcSSimon Schubert char buf[100];
83505796c8dcSSimon Schubert char *name;
83515796c8dcSSimon Schubert size_t len;
83525796c8dcSSimon Schubert asection *sect;
83535796c8dcSSimon Schubert
83545796c8dcSSimon Schubert if (note->descsz != sizeof (lwpstat)
83555796c8dcSSimon Schubert #if defined (HAVE_LWPXSTATUS_T)
83565796c8dcSSimon Schubert && note->descsz != sizeof (lwpxstatus_t)
83575796c8dcSSimon Schubert #endif
83585796c8dcSSimon Schubert )
83595796c8dcSSimon Schubert return TRUE;
83605796c8dcSSimon Schubert
83615796c8dcSSimon Schubert memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
83625796c8dcSSimon Schubert
8363*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
8364cf7f2e2dSJohn Marino /* Do not overwrite the core signal if it has already been set by
8365cf7f2e2dSJohn Marino another thread. */
8366*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->core->signal == 0)
8367*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;
83685796c8dcSSimon Schubert
83695796c8dcSSimon Schubert /* Make a ".reg/999" section. */
83705796c8dcSSimon Schubert
83715796c8dcSSimon Schubert sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
83725796c8dcSSimon Schubert len = strlen (buf) + 1;
83735796c8dcSSimon Schubert name = bfd_alloc (abfd, len);
83745796c8dcSSimon Schubert if (name == NULL)
83755796c8dcSSimon Schubert return FALSE;
83765796c8dcSSimon Schubert memcpy (name, buf, len);
83775796c8dcSSimon Schubert
83785796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
83795796c8dcSSimon Schubert if (sect == NULL)
83805796c8dcSSimon Schubert return FALSE;
83815796c8dcSSimon Schubert
83825796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
83835796c8dcSSimon Schubert sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
83845796c8dcSSimon Schubert sect->filepos = note->descpos
83855796c8dcSSimon Schubert + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
83865796c8dcSSimon Schubert #endif
83875796c8dcSSimon Schubert
83885796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_REG)
83895796c8dcSSimon Schubert sect->size = sizeof (lwpstat.pr_reg);
83905796c8dcSSimon Schubert sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
83915796c8dcSSimon Schubert #endif
83925796c8dcSSimon Schubert
83935796c8dcSSimon Schubert sect->alignment_power = 2;
83945796c8dcSSimon Schubert
83955796c8dcSSimon Schubert if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
83965796c8dcSSimon Schubert return FALSE;
83975796c8dcSSimon Schubert
83985796c8dcSSimon Schubert /* Make a ".reg2/999" section */
83995796c8dcSSimon Schubert
84005796c8dcSSimon Schubert sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
84015796c8dcSSimon Schubert len = strlen (buf) + 1;
84025796c8dcSSimon Schubert name = bfd_alloc (abfd, len);
84035796c8dcSSimon Schubert if (name == NULL)
84045796c8dcSSimon Schubert return FALSE;
84055796c8dcSSimon Schubert memcpy (name, buf, len);
84065796c8dcSSimon Schubert
84075796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
84085796c8dcSSimon Schubert if (sect == NULL)
84095796c8dcSSimon Schubert return FALSE;
84105796c8dcSSimon Schubert
84115796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
84125796c8dcSSimon Schubert sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
84135796c8dcSSimon Schubert sect->filepos = note->descpos
84145796c8dcSSimon Schubert + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
84155796c8dcSSimon Schubert #endif
84165796c8dcSSimon Schubert
84175796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_FPREG)
84185796c8dcSSimon Schubert sect->size = sizeof (lwpstat.pr_fpreg);
84195796c8dcSSimon Schubert sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
84205796c8dcSSimon Schubert #endif
84215796c8dcSSimon Schubert
84225796c8dcSSimon Schubert sect->alignment_power = 2;
84235796c8dcSSimon Schubert
84245796c8dcSSimon Schubert return elfcore_maybe_make_sect (abfd, ".reg2", sect);
84255796c8dcSSimon Schubert }
84265796c8dcSSimon Schubert #endif /* defined (HAVE_LWPSTATUS_T) */
84275796c8dcSSimon Schubert
84285796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_win32pstatus(bfd * abfd,Elf_Internal_Note * note)84295796c8dcSSimon Schubert elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
84305796c8dcSSimon Schubert {
84315796c8dcSSimon Schubert char buf[30];
84325796c8dcSSimon Schubert char *name;
84335796c8dcSSimon Schubert size_t len;
84345796c8dcSSimon Schubert asection *sect;
84355796c8dcSSimon Schubert int type;
84365796c8dcSSimon Schubert int is_active_thread;
84375796c8dcSSimon Schubert bfd_vma base_addr;
84385796c8dcSSimon Schubert
84395796c8dcSSimon Schubert if (note->descsz < 728)
84405796c8dcSSimon Schubert return TRUE;
84415796c8dcSSimon Schubert
84425796c8dcSSimon Schubert if (! CONST_STRNEQ (note->namedata, "win32"))
84435796c8dcSSimon Schubert return TRUE;
84445796c8dcSSimon Schubert
84455796c8dcSSimon Schubert type = bfd_get_32 (abfd, note->descdata);
84465796c8dcSSimon Schubert
84475796c8dcSSimon Schubert switch (type)
84485796c8dcSSimon Schubert {
84495796c8dcSSimon Schubert case 1 /* NOTE_INFO_PROCESS */:
8450*ef5ccd6cSJohn Marino /* FIXME: need to add ->core->command. */
84515796c8dcSSimon Schubert /* process_info.pid */
8452*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 8);
84535796c8dcSSimon Schubert /* process_info.signal */
8454*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 12);
84555796c8dcSSimon Schubert break;
84565796c8dcSSimon Schubert
84575796c8dcSSimon Schubert case 2 /* NOTE_INFO_THREAD */:
84585796c8dcSSimon Schubert /* Make a ".reg/999" section. */
84595796c8dcSSimon Schubert /* thread_info.tid */
84605796c8dcSSimon Schubert sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8));
84615796c8dcSSimon Schubert
84625796c8dcSSimon Schubert len = strlen (buf) + 1;
84635796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, len);
84645796c8dcSSimon Schubert if (name == NULL)
84655796c8dcSSimon Schubert return FALSE;
84665796c8dcSSimon Schubert
84675796c8dcSSimon Schubert memcpy (name, buf, len);
84685796c8dcSSimon Schubert
84695796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
84705796c8dcSSimon Schubert if (sect == NULL)
84715796c8dcSSimon Schubert return FALSE;
84725796c8dcSSimon Schubert
84735796c8dcSSimon Schubert /* sizeof (thread_info.thread_context) */
84745796c8dcSSimon Schubert sect->size = 716;
84755796c8dcSSimon Schubert /* offsetof (thread_info.thread_context) */
84765796c8dcSSimon Schubert sect->filepos = note->descpos + 12;
84775796c8dcSSimon Schubert sect->alignment_power = 2;
84785796c8dcSSimon Schubert
84795796c8dcSSimon Schubert /* thread_info.is_active_thread */
84805796c8dcSSimon Schubert is_active_thread = bfd_get_32 (abfd, note->descdata + 8);
84815796c8dcSSimon Schubert
84825796c8dcSSimon Schubert if (is_active_thread)
84835796c8dcSSimon Schubert if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
84845796c8dcSSimon Schubert return FALSE;
84855796c8dcSSimon Schubert break;
84865796c8dcSSimon Schubert
84875796c8dcSSimon Schubert case 3 /* NOTE_INFO_MODULE */:
84885796c8dcSSimon Schubert /* Make a ".module/xxxxxxxx" section. */
84895796c8dcSSimon Schubert /* module_info.base_address */
84905796c8dcSSimon Schubert base_addr = bfd_get_32 (abfd, note->descdata + 4);
84915796c8dcSSimon Schubert sprintf (buf, ".module/%08lx", (unsigned long) base_addr);
84925796c8dcSSimon Schubert
84935796c8dcSSimon Schubert len = strlen (buf) + 1;
84945796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, len);
84955796c8dcSSimon Schubert if (name == NULL)
84965796c8dcSSimon Schubert return FALSE;
84975796c8dcSSimon Schubert
84985796c8dcSSimon Schubert memcpy (name, buf, len);
84995796c8dcSSimon Schubert
85005796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
85015796c8dcSSimon Schubert
85025796c8dcSSimon Schubert if (sect == NULL)
85035796c8dcSSimon Schubert return FALSE;
85045796c8dcSSimon Schubert
85055796c8dcSSimon Schubert sect->size = note->descsz;
85065796c8dcSSimon Schubert sect->filepos = note->descpos;
85075796c8dcSSimon Schubert sect->alignment_power = 2;
85085796c8dcSSimon Schubert break;
85095796c8dcSSimon Schubert
85105796c8dcSSimon Schubert default:
85115796c8dcSSimon Schubert return TRUE;
85125796c8dcSSimon Schubert }
85135796c8dcSSimon Schubert
85145796c8dcSSimon Schubert return TRUE;
85155796c8dcSSimon Schubert }
85165796c8dcSSimon Schubert
85175796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_note(bfd * abfd,Elf_Internal_Note * note)85185796c8dcSSimon Schubert elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
85195796c8dcSSimon Schubert {
85205796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
85215796c8dcSSimon Schubert
85225796c8dcSSimon Schubert switch (note->type)
85235796c8dcSSimon Schubert {
85245796c8dcSSimon Schubert default:
85255796c8dcSSimon Schubert return TRUE;
85265796c8dcSSimon Schubert
85275796c8dcSSimon Schubert case NT_PRSTATUS:
85285796c8dcSSimon Schubert if (bed->elf_backend_grok_prstatus)
85295796c8dcSSimon Schubert if ((*bed->elf_backend_grok_prstatus) (abfd, note))
85305796c8dcSSimon Schubert return TRUE;
85315796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS_T)
85325796c8dcSSimon Schubert return elfcore_grok_prstatus (abfd, note);
85335796c8dcSSimon Schubert #else
85345796c8dcSSimon Schubert return TRUE;
85355796c8dcSSimon Schubert #endif
85365796c8dcSSimon Schubert
85375796c8dcSSimon Schubert #if defined (HAVE_PSTATUS_T)
85385796c8dcSSimon Schubert case NT_PSTATUS:
85395796c8dcSSimon Schubert return elfcore_grok_pstatus (abfd, note);
85405796c8dcSSimon Schubert #endif
85415796c8dcSSimon Schubert
85425796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T)
85435796c8dcSSimon Schubert case NT_LWPSTATUS:
85445796c8dcSSimon Schubert return elfcore_grok_lwpstatus (abfd, note);
85455796c8dcSSimon Schubert #endif
85465796c8dcSSimon Schubert
85475796c8dcSSimon Schubert case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */
85485796c8dcSSimon Schubert return elfcore_grok_prfpreg (abfd, note);
85495796c8dcSSimon Schubert
85505796c8dcSSimon Schubert case NT_WIN32PSTATUS:
85515796c8dcSSimon Schubert return elfcore_grok_win32pstatus (abfd, note);
85525796c8dcSSimon Schubert
85535796c8dcSSimon Schubert case NT_PRXFPREG: /* Linux SSE extension */
85545796c8dcSSimon Schubert if (note->namesz == 6
85555796c8dcSSimon Schubert && strcmp (note->namedata, "LINUX") == 0)
85565796c8dcSSimon Schubert return elfcore_grok_prxfpreg (abfd, note);
85575796c8dcSSimon Schubert else
85585796c8dcSSimon Schubert return TRUE;
85595796c8dcSSimon Schubert
8560cf7f2e2dSJohn Marino case NT_X86_XSTATE: /* Linux XSAVE extension */
8561cf7f2e2dSJohn Marino if (note->namesz == 6
8562cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8563cf7f2e2dSJohn Marino return elfcore_grok_xstatereg (abfd, note);
8564cf7f2e2dSJohn Marino else
8565cf7f2e2dSJohn Marino return TRUE;
8566cf7f2e2dSJohn Marino
85675796c8dcSSimon Schubert case NT_PPC_VMX:
85685796c8dcSSimon Schubert if (note->namesz == 6
85695796c8dcSSimon Schubert && strcmp (note->namedata, "LINUX") == 0)
85705796c8dcSSimon Schubert return elfcore_grok_ppc_vmx (abfd, note);
85715796c8dcSSimon Schubert else
85725796c8dcSSimon Schubert return TRUE;
85735796c8dcSSimon Schubert
85745796c8dcSSimon Schubert case NT_PPC_VSX:
85755796c8dcSSimon Schubert if (note->namesz == 6
85765796c8dcSSimon Schubert && strcmp (note->namedata, "LINUX") == 0)
85775796c8dcSSimon Schubert return elfcore_grok_ppc_vsx (abfd, note);
85785796c8dcSSimon Schubert else
85795796c8dcSSimon Schubert return TRUE;
85805796c8dcSSimon Schubert
8581cf7f2e2dSJohn Marino case NT_S390_HIGH_GPRS:
8582cf7f2e2dSJohn Marino if (note->namesz == 6
8583cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8584cf7f2e2dSJohn Marino return elfcore_grok_s390_high_gprs (abfd, note);
8585cf7f2e2dSJohn Marino else
8586cf7f2e2dSJohn Marino return TRUE;
8587cf7f2e2dSJohn Marino
8588cf7f2e2dSJohn Marino case NT_S390_TIMER:
8589cf7f2e2dSJohn Marino if (note->namesz == 6
8590cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8591cf7f2e2dSJohn Marino return elfcore_grok_s390_timer (abfd, note);
8592cf7f2e2dSJohn Marino else
8593cf7f2e2dSJohn Marino return TRUE;
8594cf7f2e2dSJohn Marino
8595cf7f2e2dSJohn Marino case NT_S390_TODCMP:
8596cf7f2e2dSJohn Marino if (note->namesz == 6
8597cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8598cf7f2e2dSJohn Marino return elfcore_grok_s390_todcmp (abfd, note);
8599cf7f2e2dSJohn Marino else
8600cf7f2e2dSJohn Marino return TRUE;
8601cf7f2e2dSJohn Marino
8602cf7f2e2dSJohn Marino case NT_S390_TODPREG:
8603cf7f2e2dSJohn Marino if (note->namesz == 6
8604cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8605cf7f2e2dSJohn Marino return elfcore_grok_s390_todpreg (abfd, note);
8606cf7f2e2dSJohn Marino else
8607cf7f2e2dSJohn Marino return TRUE;
8608cf7f2e2dSJohn Marino
8609cf7f2e2dSJohn Marino case NT_S390_CTRS:
8610cf7f2e2dSJohn Marino if (note->namesz == 6
8611cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8612cf7f2e2dSJohn Marino return elfcore_grok_s390_ctrs (abfd, note);
8613cf7f2e2dSJohn Marino else
8614cf7f2e2dSJohn Marino return TRUE;
8615cf7f2e2dSJohn Marino
8616cf7f2e2dSJohn Marino case NT_S390_PREFIX:
8617cf7f2e2dSJohn Marino if (note->namesz == 6
8618cf7f2e2dSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8619cf7f2e2dSJohn Marino return elfcore_grok_s390_prefix (abfd, note);
8620cf7f2e2dSJohn Marino else
8621cf7f2e2dSJohn Marino return TRUE;
8622cf7f2e2dSJohn Marino
8623a45ae5f8SJohn Marino case NT_S390_LAST_BREAK:
8624a45ae5f8SJohn Marino if (note->namesz == 6
8625a45ae5f8SJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8626a45ae5f8SJohn Marino return elfcore_grok_s390_last_break (abfd, note);
8627a45ae5f8SJohn Marino else
8628a45ae5f8SJohn Marino return TRUE;
8629a45ae5f8SJohn Marino
8630a45ae5f8SJohn Marino case NT_S390_SYSTEM_CALL:
8631a45ae5f8SJohn Marino if (note->namesz == 6
8632a45ae5f8SJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8633a45ae5f8SJohn Marino return elfcore_grok_s390_system_call (abfd, note);
8634a45ae5f8SJohn Marino else
8635a45ae5f8SJohn Marino return TRUE;
8636a45ae5f8SJohn Marino
8637*ef5ccd6cSJohn Marino case NT_S390_TDB:
8638*ef5ccd6cSJohn Marino if (note->namesz == 6
8639*ef5ccd6cSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8640*ef5ccd6cSJohn Marino return elfcore_grok_s390_tdb (abfd, note);
8641*ef5ccd6cSJohn Marino else
8642*ef5ccd6cSJohn Marino return TRUE;
8643*ef5ccd6cSJohn Marino
8644a45ae5f8SJohn Marino case NT_ARM_VFP:
8645a45ae5f8SJohn Marino if (note->namesz == 6
8646a45ae5f8SJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8647a45ae5f8SJohn Marino return elfcore_grok_arm_vfp (abfd, note);
8648a45ae5f8SJohn Marino else
8649a45ae5f8SJohn Marino return TRUE;
8650a45ae5f8SJohn Marino
8651*ef5ccd6cSJohn Marino case NT_ARM_TLS:
8652*ef5ccd6cSJohn Marino if (note->namesz == 6
8653*ef5ccd6cSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8654*ef5ccd6cSJohn Marino return elfcore_grok_aarch_tls (abfd, note);
8655*ef5ccd6cSJohn Marino else
8656*ef5ccd6cSJohn Marino return TRUE;
8657*ef5ccd6cSJohn Marino
8658*ef5ccd6cSJohn Marino case NT_ARM_HW_BREAK:
8659*ef5ccd6cSJohn Marino if (note->namesz == 6
8660*ef5ccd6cSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8661*ef5ccd6cSJohn Marino return elfcore_grok_aarch_hw_break (abfd, note);
8662*ef5ccd6cSJohn Marino else
8663*ef5ccd6cSJohn Marino return TRUE;
8664*ef5ccd6cSJohn Marino
8665*ef5ccd6cSJohn Marino case NT_ARM_HW_WATCH:
8666*ef5ccd6cSJohn Marino if (note->namesz == 6
8667*ef5ccd6cSJohn Marino && strcmp (note->namedata, "LINUX") == 0)
8668*ef5ccd6cSJohn Marino return elfcore_grok_aarch_hw_watch (abfd, note);
8669*ef5ccd6cSJohn Marino else
8670*ef5ccd6cSJohn Marino return TRUE;
8671*ef5ccd6cSJohn Marino
86725796c8dcSSimon Schubert case NT_PRPSINFO:
86735796c8dcSSimon Schubert case NT_PSINFO:
86745796c8dcSSimon Schubert if (bed->elf_backend_grok_psinfo)
86755796c8dcSSimon Schubert if ((*bed->elf_backend_grok_psinfo) (abfd, note))
86765796c8dcSSimon Schubert return TRUE;
86775796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
86785796c8dcSSimon Schubert return elfcore_grok_psinfo (abfd, note);
86795796c8dcSSimon Schubert #else
86805796c8dcSSimon Schubert return TRUE;
86815796c8dcSSimon Schubert #endif
86825796c8dcSSimon Schubert
86835796c8dcSSimon Schubert case NT_AUXV:
86845796c8dcSSimon Schubert {
86855796c8dcSSimon Schubert asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
86865796c8dcSSimon Schubert SEC_HAS_CONTENTS);
86875796c8dcSSimon Schubert
86885796c8dcSSimon Schubert if (sect == NULL)
86895796c8dcSSimon Schubert return FALSE;
86905796c8dcSSimon Schubert sect->size = note->descsz;
86915796c8dcSSimon Schubert sect->filepos = note->descpos;
86925796c8dcSSimon Schubert sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
86935796c8dcSSimon Schubert
86945796c8dcSSimon Schubert return TRUE;
86955796c8dcSSimon Schubert }
8696*ef5ccd6cSJohn Marino
8697*ef5ccd6cSJohn Marino case NT_FILE:
8698*ef5ccd6cSJohn Marino return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
8699*ef5ccd6cSJohn Marino note);
8700*ef5ccd6cSJohn Marino
8701*ef5ccd6cSJohn Marino case NT_SIGINFO:
8702*ef5ccd6cSJohn Marino return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
8703*ef5ccd6cSJohn Marino note);
87045796c8dcSSimon Schubert }
87055796c8dcSSimon Schubert }
87065796c8dcSSimon Schubert
87075796c8dcSSimon Schubert static bfd_boolean
elfobj_grok_gnu_build_id(bfd * abfd,Elf_Internal_Note * note)87085796c8dcSSimon Schubert elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
87095796c8dcSSimon Schubert {
8710*ef5ccd6cSJohn Marino struct elf_obj_tdata *t;
8711*ef5ccd6cSJohn Marino
8712*ef5ccd6cSJohn Marino if (note->descsz == 0)
87135796c8dcSSimon Schubert return FALSE;
87145796c8dcSSimon Schubert
8715*ef5ccd6cSJohn Marino t = elf_tdata (abfd);
8716*ef5ccd6cSJohn Marino t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
8717*ef5ccd6cSJohn Marino if (t->build_id == NULL)
8718*ef5ccd6cSJohn Marino return FALSE;
8719*ef5ccd6cSJohn Marino
8720*ef5ccd6cSJohn Marino t->build_id->size = note->descsz;
8721*ef5ccd6cSJohn Marino memcpy (t->build_id->data, note->descdata, note->descsz);
87225796c8dcSSimon Schubert
87235796c8dcSSimon Schubert return TRUE;
87245796c8dcSSimon Schubert }
87255796c8dcSSimon Schubert
87265796c8dcSSimon Schubert static bfd_boolean
elfobj_grok_gnu_note(bfd * abfd,Elf_Internal_Note * note)87275796c8dcSSimon Schubert elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
87285796c8dcSSimon Schubert {
87295796c8dcSSimon Schubert switch (note->type)
87305796c8dcSSimon Schubert {
87315796c8dcSSimon Schubert default:
87325796c8dcSSimon Schubert return TRUE;
87335796c8dcSSimon Schubert
87345796c8dcSSimon Schubert case NT_GNU_BUILD_ID:
87355796c8dcSSimon Schubert return elfobj_grok_gnu_build_id (abfd, note);
87365796c8dcSSimon Schubert }
87375796c8dcSSimon Schubert }
87385796c8dcSSimon Schubert
87395796c8dcSSimon Schubert static bfd_boolean
elfobj_grok_stapsdt_note_1(bfd * abfd,Elf_Internal_Note * note)8740a45ae5f8SJohn Marino elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note)
8741a45ae5f8SJohn Marino {
8742a45ae5f8SJohn Marino struct sdt_note *cur =
8743a45ae5f8SJohn Marino (struct sdt_note *) bfd_alloc (abfd, sizeof (struct sdt_note)
8744a45ae5f8SJohn Marino + note->descsz);
8745a45ae5f8SJohn Marino
8746a45ae5f8SJohn Marino cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head;
8747a45ae5f8SJohn Marino cur->size = (bfd_size_type) note->descsz;
8748a45ae5f8SJohn Marino memcpy (cur->data, note->descdata, note->descsz);
8749a45ae5f8SJohn Marino
8750a45ae5f8SJohn Marino elf_tdata (abfd)->sdt_note_head = cur;
8751a45ae5f8SJohn Marino
8752a45ae5f8SJohn Marino return TRUE;
8753a45ae5f8SJohn Marino }
8754a45ae5f8SJohn Marino
8755a45ae5f8SJohn Marino static bfd_boolean
elfobj_grok_stapsdt_note(bfd * abfd,Elf_Internal_Note * note)8756a45ae5f8SJohn Marino elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
8757a45ae5f8SJohn Marino {
8758a45ae5f8SJohn Marino switch (note->type)
8759a45ae5f8SJohn Marino {
8760a45ae5f8SJohn Marino case NT_STAPSDT:
8761a45ae5f8SJohn Marino return elfobj_grok_stapsdt_note_1 (abfd, note);
8762a45ae5f8SJohn Marino
8763a45ae5f8SJohn Marino default:
8764a45ae5f8SJohn Marino return TRUE;
8765a45ae5f8SJohn Marino }
8766a45ae5f8SJohn Marino }
8767a45ae5f8SJohn Marino
8768a45ae5f8SJohn Marino static bfd_boolean
elfcore_netbsd_get_lwpid(Elf_Internal_Note * note,int * lwpidp)87695796c8dcSSimon Schubert elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
87705796c8dcSSimon Schubert {
87715796c8dcSSimon Schubert char *cp;
87725796c8dcSSimon Schubert
87735796c8dcSSimon Schubert cp = strchr (note->namedata, '@');
87745796c8dcSSimon Schubert if (cp != NULL)
87755796c8dcSSimon Schubert {
87765796c8dcSSimon Schubert *lwpidp = atoi(cp + 1);
87775796c8dcSSimon Schubert return TRUE;
87785796c8dcSSimon Schubert }
87795796c8dcSSimon Schubert return FALSE;
87805796c8dcSSimon Schubert }
87815796c8dcSSimon Schubert
87825796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_netbsd_procinfo(bfd * abfd,Elf_Internal_Note * note)87835796c8dcSSimon Schubert elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
87845796c8dcSSimon Schubert {
87855796c8dcSSimon Schubert /* Signal number at offset 0x08. */
8786*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal
87875796c8dcSSimon Schubert = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
87885796c8dcSSimon Schubert
87895796c8dcSSimon Schubert /* Process ID at offset 0x50. */
8790*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid
87915796c8dcSSimon Schubert = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
87925796c8dcSSimon Schubert
87935796c8dcSSimon Schubert /* Command name at 0x7c (max 32 bytes, including nul). */
8794*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->command
87955796c8dcSSimon Schubert = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
87965796c8dcSSimon Schubert
87975796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
87985796c8dcSSimon Schubert note);
87995796c8dcSSimon Schubert }
88005796c8dcSSimon Schubert
88015796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_netbsd_note(bfd * abfd,Elf_Internal_Note * note)88025796c8dcSSimon Schubert elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
88035796c8dcSSimon Schubert {
88045796c8dcSSimon Schubert int lwp;
88055796c8dcSSimon Schubert
88065796c8dcSSimon Schubert if (elfcore_netbsd_get_lwpid (note, &lwp))
8807*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = lwp;
88085796c8dcSSimon Schubert
88095796c8dcSSimon Schubert if (note->type == NT_NETBSDCORE_PROCINFO)
88105796c8dcSSimon Schubert {
88115796c8dcSSimon Schubert /* NetBSD-specific core "procinfo". Note that we expect to
88125796c8dcSSimon Schubert find this note before any of the others, which is fine,
88135796c8dcSSimon Schubert since the kernel writes this note out first when it
88145796c8dcSSimon Schubert creates a core file. */
88155796c8dcSSimon Schubert
88165796c8dcSSimon Schubert return elfcore_grok_netbsd_procinfo (abfd, note);
88175796c8dcSSimon Schubert }
88185796c8dcSSimon Schubert
88195796c8dcSSimon Schubert /* As of Jan 2002 there are no other machine-independent notes
88205796c8dcSSimon Schubert defined for NetBSD core files. If the note type is less
88215796c8dcSSimon Schubert than the start of the machine-dependent note types, we don't
88225796c8dcSSimon Schubert understand it. */
88235796c8dcSSimon Schubert
88245796c8dcSSimon Schubert if (note->type < NT_NETBSDCORE_FIRSTMACH)
88255796c8dcSSimon Schubert return TRUE;
88265796c8dcSSimon Schubert
88275796c8dcSSimon Schubert
88285796c8dcSSimon Schubert switch (bfd_get_arch (abfd))
88295796c8dcSSimon Schubert {
88305796c8dcSSimon Schubert /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
88315796c8dcSSimon Schubert PT_GETFPREGS == mach+2. */
88325796c8dcSSimon Schubert
88335796c8dcSSimon Schubert case bfd_arch_alpha:
88345796c8dcSSimon Schubert case bfd_arch_sparc:
88355796c8dcSSimon Schubert switch (note->type)
88365796c8dcSSimon Schubert {
88375796c8dcSSimon Schubert case NT_NETBSDCORE_FIRSTMACH+0:
88385796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg", note);
88395796c8dcSSimon Schubert
88405796c8dcSSimon Schubert case NT_NETBSDCORE_FIRSTMACH+2:
88415796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg2", note);
88425796c8dcSSimon Schubert
88435796c8dcSSimon Schubert default:
88445796c8dcSSimon Schubert return TRUE;
88455796c8dcSSimon Schubert }
88465796c8dcSSimon Schubert
88475796c8dcSSimon Schubert /* On all other arch's, PT_GETREGS == mach+1 and
88485796c8dcSSimon Schubert PT_GETFPREGS == mach+3. */
88495796c8dcSSimon Schubert
88505796c8dcSSimon Schubert default:
88515796c8dcSSimon Schubert switch (note->type)
88525796c8dcSSimon Schubert {
88535796c8dcSSimon Schubert case NT_NETBSDCORE_FIRSTMACH+1:
88545796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg", note);
88555796c8dcSSimon Schubert
88565796c8dcSSimon Schubert case NT_NETBSDCORE_FIRSTMACH+3:
88575796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg2", note);
88585796c8dcSSimon Schubert
88595796c8dcSSimon Schubert default:
88605796c8dcSSimon Schubert return TRUE;
88615796c8dcSSimon Schubert }
88625796c8dcSSimon Schubert }
88635796c8dcSSimon Schubert /* NOTREACHED */
88645796c8dcSSimon Schubert }
88655796c8dcSSimon Schubert
88665796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_openbsd_procinfo(bfd * abfd,Elf_Internal_Note * note)88675796c8dcSSimon Schubert elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
88685796c8dcSSimon Schubert {
88695796c8dcSSimon Schubert /* Signal number at offset 0x08. */
8870*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal
88715796c8dcSSimon Schubert = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
88725796c8dcSSimon Schubert
88735796c8dcSSimon Schubert /* Process ID at offset 0x20. */
8874*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid
88755796c8dcSSimon Schubert = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
88765796c8dcSSimon Schubert
88775796c8dcSSimon Schubert /* Command name at 0x48 (max 32 bytes, including nul). */
8878*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->command
88795796c8dcSSimon Schubert = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
88805796c8dcSSimon Schubert
88815796c8dcSSimon Schubert return TRUE;
88825796c8dcSSimon Schubert }
88835796c8dcSSimon Schubert
88845796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_openbsd_note(bfd * abfd,Elf_Internal_Note * note)88855796c8dcSSimon Schubert elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
88865796c8dcSSimon Schubert {
88875796c8dcSSimon Schubert if (note->type == NT_OPENBSD_PROCINFO)
88885796c8dcSSimon Schubert return elfcore_grok_openbsd_procinfo (abfd, note);
88895796c8dcSSimon Schubert
88905796c8dcSSimon Schubert if (note->type == NT_OPENBSD_REGS)
88915796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg", note);
88925796c8dcSSimon Schubert
88935796c8dcSSimon Schubert if (note->type == NT_OPENBSD_FPREGS)
88945796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg2", note);
88955796c8dcSSimon Schubert
88965796c8dcSSimon Schubert if (note->type == NT_OPENBSD_XFPREGS)
88975796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
88985796c8dcSSimon Schubert
88995796c8dcSSimon Schubert if (note->type == NT_OPENBSD_AUXV)
89005796c8dcSSimon Schubert {
89015796c8dcSSimon Schubert asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
89025796c8dcSSimon Schubert SEC_HAS_CONTENTS);
89035796c8dcSSimon Schubert
89045796c8dcSSimon Schubert if (sect == NULL)
89055796c8dcSSimon Schubert return FALSE;
89065796c8dcSSimon Schubert sect->size = note->descsz;
89075796c8dcSSimon Schubert sect->filepos = note->descpos;
89085796c8dcSSimon Schubert sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
89095796c8dcSSimon Schubert
89105796c8dcSSimon Schubert return TRUE;
89115796c8dcSSimon Schubert }
89125796c8dcSSimon Schubert
89135796c8dcSSimon Schubert if (note->type == NT_OPENBSD_WCOOKIE)
89145796c8dcSSimon Schubert {
89155796c8dcSSimon Schubert asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
89165796c8dcSSimon Schubert SEC_HAS_CONTENTS);
89175796c8dcSSimon Schubert
89185796c8dcSSimon Schubert if (sect == NULL)
89195796c8dcSSimon Schubert return FALSE;
89205796c8dcSSimon Schubert sect->size = note->descsz;
89215796c8dcSSimon Schubert sect->filepos = note->descpos;
89225796c8dcSSimon Schubert sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
89235796c8dcSSimon Schubert
89245796c8dcSSimon Schubert return TRUE;
89255796c8dcSSimon Schubert }
89265796c8dcSSimon Schubert
89275796c8dcSSimon Schubert return TRUE;
89285796c8dcSSimon Schubert }
89295796c8dcSSimon Schubert
89305796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_nto_status(bfd * abfd,Elf_Internal_Note * note,long * tid)89315796c8dcSSimon Schubert elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
89325796c8dcSSimon Schubert {
89335796c8dcSSimon Schubert void *ddata = note->descdata;
89345796c8dcSSimon Schubert char buf[100];
89355796c8dcSSimon Schubert char *name;
89365796c8dcSSimon Schubert asection *sect;
89375796c8dcSSimon Schubert short sig;
89385796c8dcSSimon Schubert unsigned flags;
89395796c8dcSSimon Schubert
89405796c8dcSSimon Schubert /* nto_procfs_status 'pid' field is at offset 0. */
8941*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
89425796c8dcSSimon Schubert
89435796c8dcSSimon Schubert /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */
89445796c8dcSSimon Schubert *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
89455796c8dcSSimon Schubert
89465796c8dcSSimon Schubert /* nto_procfs_status 'flags' field is at offset 8. */
89475796c8dcSSimon Schubert flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
89485796c8dcSSimon Schubert
89495796c8dcSSimon Schubert /* nto_procfs_status 'what' field is at offset 14. */
89505796c8dcSSimon Schubert if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
89515796c8dcSSimon Schubert {
8952*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->signal = sig;
8953*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = *tid;
89545796c8dcSSimon Schubert }
89555796c8dcSSimon Schubert
89565796c8dcSSimon Schubert /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores
89575796c8dcSSimon Schubert do not come from signals so we make sure we set the current
89585796c8dcSSimon Schubert thread just in case. */
89595796c8dcSSimon Schubert if (flags & 0x00000080)
8960*ef5ccd6cSJohn Marino elf_tdata (abfd)->core->lwpid = *tid;
89615796c8dcSSimon Schubert
89625796c8dcSSimon Schubert /* Make a ".qnx_core_status/%d" section. */
89635796c8dcSSimon Schubert sprintf (buf, ".qnx_core_status/%ld", *tid);
89645796c8dcSSimon Schubert
89655796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
89665796c8dcSSimon Schubert if (name == NULL)
89675796c8dcSSimon Schubert return FALSE;
89685796c8dcSSimon Schubert strcpy (name, buf);
89695796c8dcSSimon Schubert
89705796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
89715796c8dcSSimon Schubert if (sect == NULL)
89725796c8dcSSimon Schubert return FALSE;
89735796c8dcSSimon Schubert
89745796c8dcSSimon Schubert sect->size = note->descsz;
89755796c8dcSSimon Schubert sect->filepos = note->descpos;
89765796c8dcSSimon Schubert sect->alignment_power = 2;
89775796c8dcSSimon Schubert
89785796c8dcSSimon Schubert return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
89795796c8dcSSimon Schubert }
89805796c8dcSSimon Schubert
89815796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_nto_regs(bfd * abfd,Elf_Internal_Note * note,long tid,char * base)89825796c8dcSSimon Schubert elfcore_grok_nto_regs (bfd *abfd,
89835796c8dcSSimon Schubert Elf_Internal_Note *note,
89845796c8dcSSimon Schubert long tid,
89855796c8dcSSimon Schubert char *base)
89865796c8dcSSimon Schubert {
89875796c8dcSSimon Schubert char buf[100];
89885796c8dcSSimon Schubert char *name;
89895796c8dcSSimon Schubert asection *sect;
89905796c8dcSSimon Schubert
89915796c8dcSSimon Schubert /* Make a "(base)/%d" section. */
89925796c8dcSSimon Schubert sprintf (buf, "%s/%ld", base, tid);
89935796c8dcSSimon Schubert
89945796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
89955796c8dcSSimon Schubert if (name == NULL)
89965796c8dcSSimon Schubert return FALSE;
89975796c8dcSSimon Schubert strcpy (name, buf);
89985796c8dcSSimon Schubert
89995796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
90005796c8dcSSimon Schubert if (sect == NULL)
90015796c8dcSSimon Schubert return FALSE;
90025796c8dcSSimon Schubert
90035796c8dcSSimon Schubert sect->size = note->descsz;
90045796c8dcSSimon Schubert sect->filepos = note->descpos;
90055796c8dcSSimon Schubert sect->alignment_power = 2;
90065796c8dcSSimon Schubert
90075796c8dcSSimon Schubert /* This is the current thread. */
9008*ef5ccd6cSJohn Marino if (elf_tdata (abfd)->core->lwpid == tid)
90095796c8dcSSimon Schubert return elfcore_maybe_make_sect (abfd, base, sect);
90105796c8dcSSimon Schubert
90115796c8dcSSimon Schubert return TRUE;
90125796c8dcSSimon Schubert }
90135796c8dcSSimon Schubert
90145796c8dcSSimon Schubert #define BFD_QNT_CORE_INFO 7
90155796c8dcSSimon Schubert #define BFD_QNT_CORE_STATUS 8
90165796c8dcSSimon Schubert #define BFD_QNT_CORE_GREG 9
90175796c8dcSSimon Schubert #define BFD_QNT_CORE_FPREG 10
90185796c8dcSSimon Schubert
90195796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_nto_note(bfd * abfd,Elf_Internal_Note * note)90205796c8dcSSimon Schubert elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
90215796c8dcSSimon Schubert {
90225796c8dcSSimon Schubert /* Every GREG section has a STATUS section before it. Store the
90235796c8dcSSimon Schubert tid from the previous call to pass down to the next gregs
90245796c8dcSSimon Schubert function. */
90255796c8dcSSimon Schubert static long tid = 1;
90265796c8dcSSimon Schubert
90275796c8dcSSimon Schubert switch (note->type)
90285796c8dcSSimon Schubert {
90295796c8dcSSimon Schubert case BFD_QNT_CORE_INFO:
90305796c8dcSSimon Schubert return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
90315796c8dcSSimon Schubert case BFD_QNT_CORE_STATUS:
90325796c8dcSSimon Schubert return elfcore_grok_nto_status (abfd, note, &tid);
90335796c8dcSSimon Schubert case BFD_QNT_CORE_GREG:
90345796c8dcSSimon Schubert return elfcore_grok_nto_regs (abfd, note, tid, ".reg");
90355796c8dcSSimon Schubert case BFD_QNT_CORE_FPREG:
90365796c8dcSSimon Schubert return elfcore_grok_nto_regs (abfd, note, tid, ".reg2");
90375796c8dcSSimon Schubert default:
90385796c8dcSSimon Schubert return TRUE;
90395796c8dcSSimon Schubert }
90405796c8dcSSimon Schubert }
90415796c8dcSSimon Schubert
90425796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_spu_note(bfd * abfd,Elf_Internal_Note * note)90435796c8dcSSimon Schubert elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note)
90445796c8dcSSimon Schubert {
90455796c8dcSSimon Schubert char *name;
90465796c8dcSSimon Schubert asection *sect;
90475796c8dcSSimon Schubert size_t len;
90485796c8dcSSimon Schubert
90495796c8dcSSimon Schubert /* Use note name as section name. */
90505796c8dcSSimon Schubert len = note->namesz;
90515796c8dcSSimon Schubert name = (char *) bfd_alloc (abfd, len);
90525796c8dcSSimon Schubert if (name == NULL)
90535796c8dcSSimon Schubert return FALSE;
90545796c8dcSSimon Schubert memcpy (name, note->namedata, len);
90555796c8dcSSimon Schubert name[len - 1] = '\0';
90565796c8dcSSimon Schubert
90575796c8dcSSimon Schubert sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
90585796c8dcSSimon Schubert if (sect == NULL)
90595796c8dcSSimon Schubert return FALSE;
90605796c8dcSSimon Schubert
90615796c8dcSSimon Schubert sect->size = note->descsz;
90625796c8dcSSimon Schubert sect->filepos = note->descpos;
90635796c8dcSSimon Schubert sect->alignment_power = 1;
90645796c8dcSSimon Schubert
90655796c8dcSSimon Schubert return TRUE;
90665796c8dcSSimon Schubert }
90675796c8dcSSimon Schubert
90685796c8dcSSimon Schubert /* Function: elfcore_write_note
90695796c8dcSSimon Schubert
90705796c8dcSSimon Schubert Inputs:
90715796c8dcSSimon Schubert buffer to hold note, and current size of buffer
90725796c8dcSSimon Schubert name of note
90735796c8dcSSimon Schubert type of note
90745796c8dcSSimon Schubert data for note
90755796c8dcSSimon Schubert size of data for note
90765796c8dcSSimon Schubert
90775796c8dcSSimon Schubert Writes note to end of buffer. ELF64 notes are written exactly as
90785796c8dcSSimon Schubert for ELF32, despite the current (as of 2006) ELF gabi specifying
90795796c8dcSSimon Schubert that they ought to have 8-byte namesz and descsz field, and have
90805796c8dcSSimon Schubert 8-byte alignment. Other writers, eg. Linux kernel, do the same.
90815796c8dcSSimon Schubert
90825796c8dcSSimon Schubert Return:
90835796c8dcSSimon Schubert Pointer to realloc'd buffer, *BUFSIZ updated. */
90845796c8dcSSimon Schubert
90855796c8dcSSimon Schubert char *
elfcore_write_note(bfd * abfd,char * buf,int * bufsiz,const char * name,int type,const void * input,int size)90865796c8dcSSimon Schubert elfcore_write_note (bfd *abfd,
90875796c8dcSSimon Schubert char *buf,
90885796c8dcSSimon Schubert int *bufsiz,
90895796c8dcSSimon Schubert const char *name,
90905796c8dcSSimon Schubert int type,
90915796c8dcSSimon Schubert const void *input,
90925796c8dcSSimon Schubert int size)
90935796c8dcSSimon Schubert {
90945796c8dcSSimon Schubert Elf_External_Note *xnp;
90955796c8dcSSimon Schubert size_t namesz;
90965796c8dcSSimon Schubert size_t newspace;
90975796c8dcSSimon Schubert char *dest;
90985796c8dcSSimon Schubert
90995796c8dcSSimon Schubert namesz = 0;
91005796c8dcSSimon Schubert if (name != NULL)
91015796c8dcSSimon Schubert namesz = strlen (name) + 1;
91025796c8dcSSimon Schubert
91035796c8dcSSimon Schubert newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
91045796c8dcSSimon Schubert
91055796c8dcSSimon Schubert buf = (char *) realloc (buf, *bufsiz + newspace);
91065796c8dcSSimon Schubert if (buf == NULL)
91075796c8dcSSimon Schubert return buf;
91085796c8dcSSimon Schubert dest = buf + *bufsiz;
91095796c8dcSSimon Schubert *bufsiz += newspace;
91105796c8dcSSimon Schubert xnp = (Elf_External_Note *) dest;
91115796c8dcSSimon Schubert H_PUT_32 (abfd, namesz, xnp->namesz);
91125796c8dcSSimon Schubert H_PUT_32 (abfd, size, xnp->descsz);
91135796c8dcSSimon Schubert H_PUT_32 (abfd, type, xnp->type);
91145796c8dcSSimon Schubert dest = xnp->name;
91155796c8dcSSimon Schubert if (name != NULL)
91165796c8dcSSimon Schubert {
91175796c8dcSSimon Schubert memcpy (dest, name, namesz);
91185796c8dcSSimon Schubert dest += namesz;
91195796c8dcSSimon Schubert while (namesz & 3)
91205796c8dcSSimon Schubert {
91215796c8dcSSimon Schubert *dest++ = '\0';
91225796c8dcSSimon Schubert ++namesz;
91235796c8dcSSimon Schubert }
91245796c8dcSSimon Schubert }
91255796c8dcSSimon Schubert memcpy (dest, input, size);
91265796c8dcSSimon Schubert dest += size;
91275796c8dcSSimon Schubert while (size & 3)
91285796c8dcSSimon Schubert {
91295796c8dcSSimon Schubert *dest++ = '\0';
91305796c8dcSSimon Schubert ++size;
91315796c8dcSSimon Schubert }
91325796c8dcSSimon Schubert return buf;
91335796c8dcSSimon Schubert }
91345796c8dcSSimon Schubert
91355796c8dcSSimon Schubert char *
elfcore_write_prpsinfo(bfd * abfd,char * buf,int * bufsiz,const char * fname,const char * psargs)91365796c8dcSSimon Schubert elfcore_write_prpsinfo (bfd *abfd,
91375796c8dcSSimon Schubert char *buf,
91385796c8dcSSimon Schubert int *bufsiz,
91395796c8dcSSimon Schubert const char *fname,
91405796c8dcSSimon Schubert const char *psargs)
91415796c8dcSSimon Schubert {
91425796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
91435796c8dcSSimon Schubert
91445796c8dcSSimon Schubert if (bed->elf_backend_write_core_note != NULL)
91455796c8dcSSimon Schubert {
91465796c8dcSSimon Schubert char *ret;
91475796c8dcSSimon Schubert ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
91485796c8dcSSimon Schubert NT_PRPSINFO, fname, psargs);
91495796c8dcSSimon Schubert if (ret != NULL)
91505796c8dcSSimon Schubert return ret;
91515796c8dcSSimon Schubert }
91525796c8dcSSimon Schubert
9153*ef5ccd6cSJohn Marino #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
91545796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
91555796c8dcSSimon Schubert if (bed->s->elfclass == ELFCLASS32)
91565796c8dcSSimon Schubert {
91575796c8dcSSimon Schubert #if defined (HAVE_PSINFO32_T)
91585796c8dcSSimon Schubert psinfo32_t data;
91595796c8dcSSimon Schubert int note_type = NT_PSINFO;
91605796c8dcSSimon Schubert #else
91615796c8dcSSimon Schubert prpsinfo32_t data;
91625796c8dcSSimon Schubert int note_type = NT_PRPSINFO;
91635796c8dcSSimon Schubert #endif
91645796c8dcSSimon Schubert
91655796c8dcSSimon Schubert memset (&data, 0, sizeof (data));
91665796c8dcSSimon Schubert strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
91675796c8dcSSimon Schubert strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
91685796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz,
9169*ef5ccd6cSJohn Marino "CORE", note_type, &data, sizeof (data));
91705796c8dcSSimon Schubert }
91715796c8dcSSimon Schubert else
91725796c8dcSSimon Schubert #endif
91735796c8dcSSimon Schubert {
91745796c8dcSSimon Schubert #if defined (HAVE_PSINFO_T)
91755796c8dcSSimon Schubert psinfo_t data;
91765796c8dcSSimon Schubert int note_type = NT_PSINFO;
91775796c8dcSSimon Schubert #else
91785796c8dcSSimon Schubert prpsinfo_t data;
91795796c8dcSSimon Schubert int note_type = NT_PRPSINFO;
91805796c8dcSSimon Schubert #endif
91815796c8dcSSimon Schubert
91825796c8dcSSimon Schubert memset (&data, 0, sizeof (data));
91835796c8dcSSimon Schubert strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
91845796c8dcSSimon Schubert strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
91855796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz,
9186*ef5ccd6cSJohn Marino "CORE", note_type, &data, sizeof (data));
91875796c8dcSSimon Schubert }
91885796c8dcSSimon Schubert #endif /* PSINFO_T or PRPSINFO_T */
91895796c8dcSSimon Schubert
9190*ef5ccd6cSJohn Marino free (buf);
9191*ef5ccd6cSJohn Marino return NULL;
9192*ef5ccd6cSJohn Marino }
9193*ef5ccd6cSJohn Marino
9194*ef5ccd6cSJohn Marino char *
elfcore_write_linux_prpsinfo32(bfd * abfd,char * buf,int * bufsiz,const struct elf_internal_linux_prpsinfo * prpsinfo)9195*ef5ccd6cSJohn Marino elfcore_write_linux_prpsinfo32
9196*ef5ccd6cSJohn Marino (bfd *abfd, char *buf, int *bufsiz,
9197*ef5ccd6cSJohn Marino const struct elf_internal_linux_prpsinfo *prpsinfo)
9198*ef5ccd6cSJohn Marino {
9199*ef5ccd6cSJohn Marino struct elf_external_linux_prpsinfo32 data;
9200*ef5ccd6cSJohn Marino
9201*ef5ccd6cSJohn Marino memset (&data, 0, sizeof (data));
9202*ef5ccd6cSJohn Marino LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
9203*ef5ccd6cSJohn Marino
9204*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
9205*ef5ccd6cSJohn Marino &data, sizeof (data));
9206*ef5ccd6cSJohn Marino }
9207*ef5ccd6cSJohn Marino
9208*ef5ccd6cSJohn Marino char *
elfcore_write_linux_prpsinfo64(bfd * abfd,char * buf,int * bufsiz,const struct elf_internal_linux_prpsinfo * prpsinfo)9209*ef5ccd6cSJohn Marino elfcore_write_linux_prpsinfo64
9210*ef5ccd6cSJohn Marino (bfd *abfd, char *buf, int *bufsiz,
9211*ef5ccd6cSJohn Marino const struct elf_internal_linux_prpsinfo *prpsinfo)
9212*ef5ccd6cSJohn Marino {
9213*ef5ccd6cSJohn Marino struct elf_external_linux_prpsinfo64 data;
9214*ef5ccd6cSJohn Marino
9215*ef5ccd6cSJohn Marino memset (&data, 0, sizeof (data));
9216*ef5ccd6cSJohn Marino LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
9217*ef5ccd6cSJohn Marino
9218*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9219*ef5ccd6cSJohn Marino "CORE", NT_PRPSINFO, &data, sizeof (data));
9220*ef5ccd6cSJohn Marino }
9221*ef5ccd6cSJohn Marino
92225796c8dcSSimon Schubert char *
elfcore_write_prstatus(bfd * abfd,char * buf,int * bufsiz,long pid,int cursig,const void * gregs)92235796c8dcSSimon Schubert elfcore_write_prstatus (bfd *abfd,
92245796c8dcSSimon Schubert char *buf,
92255796c8dcSSimon Schubert int *bufsiz,
92265796c8dcSSimon Schubert long pid,
92275796c8dcSSimon Schubert int cursig,
92285796c8dcSSimon Schubert const void *gregs)
92295796c8dcSSimon Schubert {
92305796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
92315796c8dcSSimon Schubert
92325796c8dcSSimon Schubert if (bed->elf_backend_write_core_note != NULL)
92335796c8dcSSimon Schubert {
92345796c8dcSSimon Schubert char *ret;
92355796c8dcSSimon Schubert ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
92365796c8dcSSimon Schubert NT_PRSTATUS,
92375796c8dcSSimon Schubert pid, cursig, gregs);
92385796c8dcSSimon Schubert if (ret != NULL)
92395796c8dcSSimon Schubert return ret;
92405796c8dcSSimon Schubert }
92415796c8dcSSimon Schubert
9242*ef5ccd6cSJohn Marino #if defined (HAVE_PRSTATUS_T)
92435796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS32_T)
92445796c8dcSSimon Schubert if (bed->s->elfclass == ELFCLASS32)
92455796c8dcSSimon Schubert {
92465796c8dcSSimon Schubert prstatus32_t prstat;
92475796c8dcSSimon Schubert
92485796c8dcSSimon Schubert memset (&prstat, 0, sizeof (prstat));
92495796c8dcSSimon Schubert prstat.pr_pid = pid;
92505796c8dcSSimon Schubert prstat.pr_cursig = cursig;
92515796c8dcSSimon Schubert memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
9252*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz, "CORE",
92535796c8dcSSimon Schubert NT_PRSTATUS, &prstat, sizeof (prstat));
92545796c8dcSSimon Schubert }
92555796c8dcSSimon Schubert else
92565796c8dcSSimon Schubert #endif
92575796c8dcSSimon Schubert {
92585796c8dcSSimon Schubert prstatus_t prstat;
92595796c8dcSSimon Schubert
92605796c8dcSSimon Schubert memset (&prstat, 0, sizeof (prstat));
92615796c8dcSSimon Schubert prstat.pr_pid = pid;
92625796c8dcSSimon Schubert prstat.pr_cursig = cursig;
92635796c8dcSSimon Schubert memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
9264*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz, "CORE",
92655796c8dcSSimon Schubert NT_PRSTATUS, &prstat, sizeof (prstat));
92665796c8dcSSimon Schubert }
92675796c8dcSSimon Schubert #endif /* HAVE_PRSTATUS_T */
92685796c8dcSSimon Schubert
9269*ef5ccd6cSJohn Marino free (buf);
9270*ef5ccd6cSJohn Marino return NULL;
9271*ef5ccd6cSJohn Marino }
9272*ef5ccd6cSJohn Marino
92735796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T)
92745796c8dcSSimon Schubert char *
elfcore_write_lwpstatus(bfd * abfd,char * buf,int * bufsiz,long pid,int cursig,const void * gregs)92755796c8dcSSimon Schubert elfcore_write_lwpstatus (bfd *abfd,
92765796c8dcSSimon Schubert char *buf,
92775796c8dcSSimon Schubert int *bufsiz,
92785796c8dcSSimon Schubert long pid,
92795796c8dcSSimon Schubert int cursig,
92805796c8dcSSimon Schubert const void *gregs)
92815796c8dcSSimon Schubert {
92825796c8dcSSimon Schubert lwpstatus_t lwpstat;
92835796c8dcSSimon Schubert const char *note_name = "CORE";
92845796c8dcSSimon Schubert
92855796c8dcSSimon Schubert memset (&lwpstat, 0, sizeof (lwpstat));
92865796c8dcSSimon Schubert lwpstat.pr_lwpid = pid >> 16;
92875796c8dcSSimon Schubert lwpstat.pr_cursig = cursig;
92885796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_REG)
92895796c8dcSSimon Schubert memcpy (lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
92905796c8dcSSimon Schubert #elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
92915796c8dcSSimon Schubert #if !defined(gregs)
92925796c8dcSSimon Schubert memcpy (lwpstat.pr_context.uc_mcontext.gregs,
92935796c8dcSSimon Schubert gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
92945796c8dcSSimon Schubert #else
92955796c8dcSSimon Schubert memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
92965796c8dcSSimon Schubert gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
92975796c8dcSSimon Schubert #endif
92985796c8dcSSimon Schubert #endif
92995796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz, note_name,
93005796c8dcSSimon Schubert NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
93015796c8dcSSimon Schubert }
93025796c8dcSSimon Schubert #endif /* HAVE_LWPSTATUS_T */
93035796c8dcSSimon Schubert
93045796c8dcSSimon Schubert #if defined (HAVE_PSTATUS_T)
93055796c8dcSSimon Schubert char *
elfcore_write_pstatus(bfd * abfd,char * buf,int * bufsiz,long pid,int cursig ATTRIBUTE_UNUSED,const void * gregs ATTRIBUTE_UNUSED)93065796c8dcSSimon Schubert elfcore_write_pstatus (bfd *abfd,
93075796c8dcSSimon Schubert char *buf,
93085796c8dcSSimon Schubert int *bufsiz,
93095796c8dcSSimon Schubert long pid,
93105796c8dcSSimon Schubert int cursig ATTRIBUTE_UNUSED,
93115796c8dcSSimon Schubert const void *gregs ATTRIBUTE_UNUSED)
93125796c8dcSSimon Schubert {
93135796c8dcSSimon Schubert const char *note_name = "CORE";
93145796c8dcSSimon Schubert #if defined (HAVE_PSTATUS32_T)
93155796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
93165796c8dcSSimon Schubert
93175796c8dcSSimon Schubert if (bed->s->elfclass == ELFCLASS32)
93185796c8dcSSimon Schubert {
93195796c8dcSSimon Schubert pstatus32_t pstat;
93205796c8dcSSimon Schubert
93215796c8dcSSimon Schubert memset (&pstat, 0, sizeof (pstat));
93225796c8dcSSimon Schubert pstat.pr_pid = pid & 0xffff;
93235796c8dcSSimon Schubert buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
93245796c8dcSSimon Schubert NT_PSTATUS, &pstat, sizeof (pstat));
93255796c8dcSSimon Schubert return buf;
93265796c8dcSSimon Schubert }
93275796c8dcSSimon Schubert else
93285796c8dcSSimon Schubert #endif
93295796c8dcSSimon Schubert {
93305796c8dcSSimon Schubert pstatus_t pstat;
93315796c8dcSSimon Schubert
93325796c8dcSSimon Schubert memset (&pstat, 0, sizeof (pstat));
93335796c8dcSSimon Schubert pstat.pr_pid = pid & 0xffff;
93345796c8dcSSimon Schubert buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
93355796c8dcSSimon Schubert NT_PSTATUS, &pstat, sizeof (pstat));
93365796c8dcSSimon Schubert return buf;
93375796c8dcSSimon Schubert }
93385796c8dcSSimon Schubert }
93395796c8dcSSimon Schubert #endif /* HAVE_PSTATUS_T */
93405796c8dcSSimon Schubert
93415796c8dcSSimon Schubert char *
elfcore_write_prfpreg(bfd * abfd,char * buf,int * bufsiz,const void * fpregs,int size)93425796c8dcSSimon Schubert elfcore_write_prfpreg (bfd *abfd,
93435796c8dcSSimon Schubert char *buf,
93445796c8dcSSimon Schubert int *bufsiz,
93455796c8dcSSimon Schubert const void *fpregs,
93465796c8dcSSimon Schubert int size)
93475796c8dcSSimon Schubert {
93485796c8dcSSimon Schubert const char *note_name = "CORE";
93495796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz,
93505796c8dcSSimon Schubert note_name, NT_FPREGSET, fpregs, size);
93515796c8dcSSimon Schubert }
93525796c8dcSSimon Schubert
93535796c8dcSSimon Schubert char *
elfcore_write_prxfpreg(bfd * abfd,char * buf,int * bufsiz,const void * xfpregs,int size)93545796c8dcSSimon Schubert elfcore_write_prxfpreg (bfd *abfd,
93555796c8dcSSimon Schubert char *buf,
93565796c8dcSSimon Schubert int *bufsiz,
93575796c8dcSSimon Schubert const void *xfpregs,
93585796c8dcSSimon Schubert int size)
93595796c8dcSSimon Schubert {
93605796c8dcSSimon Schubert char *note_name = "LINUX";
93615796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz,
93625796c8dcSSimon Schubert note_name, NT_PRXFPREG, xfpregs, size);
93635796c8dcSSimon Schubert }
93645796c8dcSSimon Schubert
93655796c8dcSSimon Schubert char *
elfcore_write_xstatereg(bfd * abfd,char * buf,int * bufsiz,const void * xfpregs,int size)9366cf7f2e2dSJohn Marino elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
9367cf7f2e2dSJohn Marino const void *xfpregs, int size)
9368cf7f2e2dSJohn Marino {
9369cf7f2e2dSJohn Marino char *note_name = "LINUX";
9370cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9371cf7f2e2dSJohn Marino note_name, NT_X86_XSTATE, xfpregs, size);
9372cf7f2e2dSJohn Marino }
9373cf7f2e2dSJohn Marino
9374cf7f2e2dSJohn Marino char *
elfcore_write_ppc_vmx(bfd * abfd,char * buf,int * bufsiz,const void * ppc_vmx,int size)93755796c8dcSSimon Schubert elfcore_write_ppc_vmx (bfd *abfd,
93765796c8dcSSimon Schubert char *buf,
93775796c8dcSSimon Schubert int *bufsiz,
93785796c8dcSSimon Schubert const void *ppc_vmx,
93795796c8dcSSimon Schubert int size)
93805796c8dcSSimon Schubert {
93815796c8dcSSimon Schubert char *note_name = "LINUX";
93825796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz,
93835796c8dcSSimon Schubert note_name, NT_PPC_VMX, ppc_vmx, size);
93845796c8dcSSimon Schubert }
93855796c8dcSSimon Schubert
93865796c8dcSSimon Schubert char *
elfcore_write_ppc_vsx(bfd * abfd,char * buf,int * bufsiz,const void * ppc_vsx,int size)93875796c8dcSSimon Schubert elfcore_write_ppc_vsx (bfd *abfd,
93885796c8dcSSimon Schubert char *buf,
93895796c8dcSSimon Schubert int *bufsiz,
93905796c8dcSSimon Schubert const void *ppc_vsx,
93915796c8dcSSimon Schubert int size)
93925796c8dcSSimon Schubert {
93935796c8dcSSimon Schubert char *note_name = "LINUX";
93945796c8dcSSimon Schubert return elfcore_write_note (abfd, buf, bufsiz,
93955796c8dcSSimon Schubert note_name, NT_PPC_VSX, ppc_vsx, size);
93965796c8dcSSimon Schubert }
93975796c8dcSSimon Schubert
9398cf7f2e2dSJohn Marino static char *
elfcore_write_s390_high_gprs(bfd * abfd,char * buf,int * bufsiz,const void * s390_high_gprs,int size)9399cf7f2e2dSJohn Marino elfcore_write_s390_high_gprs (bfd *abfd,
9400cf7f2e2dSJohn Marino char *buf,
9401cf7f2e2dSJohn Marino int *bufsiz,
9402cf7f2e2dSJohn Marino const void *s390_high_gprs,
9403cf7f2e2dSJohn Marino int size)
9404cf7f2e2dSJohn Marino {
9405cf7f2e2dSJohn Marino char *note_name = "LINUX";
9406cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9407cf7f2e2dSJohn Marino note_name, NT_S390_HIGH_GPRS,
9408cf7f2e2dSJohn Marino s390_high_gprs, size);
9409cf7f2e2dSJohn Marino }
9410cf7f2e2dSJohn Marino
9411cf7f2e2dSJohn Marino char *
elfcore_write_s390_timer(bfd * abfd,char * buf,int * bufsiz,const void * s390_timer,int size)9412cf7f2e2dSJohn Marino elfcore_write_s390_timer (bfd *abfd,
9413cf7f2e2dSJohn Marino char *buf,
9414cf7f2e2dSJohn Marino int *bufsiz,
9415cf7f2e2dSJohn Marino const void *s390_timer,
9416cf7f2e2dSJohn Marino int size)
9417cf7f2e2dSJohn Marino {
9418cf7f2e2dSJohn Marino char *note_name = "LINUX";
9419cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9420cf7f2e2dSJohn Marino note_name, NT_S390_TIMER, s390_timer, size);
9421cf7f2e2dSJohn Marino }
9422cf7f2e2dSJohn Marino
9423cf7f2e2dSJohn Marino char *
elfcore_write_s390_todcmp(bfd * abfd,char * buf,int * bufsiz,const void * s390_todcmp,int size)9424cf7f2e2dSJohn Marino elfcore_write_s390_todcmp (bfd *abfd,
9425cf7f2e2dSJohn Marino char *buf,
9426cf7f2e2dSJohn Marino int *bufsiz,
9427cf7f2e2dSJohn Marino const void *s390_todcmp,
9428cf7f2e2dSJohn Marino int size)
9429cf7f2e2dSJohn Marino {
9430cf7f2e2dSJohn Marino char *note_name = "LINUX";
9431cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9432cf7f2e2dSJohn Marino note_name, NT_S390_TODCMP, s390_todcmp, size);
9433cf7f2e2dSJohn Marino }
9434cf7f2e2dSJohn Marino
9435cf7f2e2dSJohn Marino char *
elfcore_write_s390_todpreg(bfd * abfd,char * buf,int * bufsiz,const void * s390_todpreg,int size)9436cf7f2e2dSJohn Marino elfcore_write_s390_todpreg (bfd *abfd,
9437cf7f2e2dSJohn Marino char *buf,
9438cf7f2e2dSJohn Marino int *bufsiz,
9439cf7f2e2dSJohn Marino const void *s390_todpreg,
9440cf7f2e2dSJohn Marino int size)
9441cf7f2e2dSJohn Marino {
9442cf7f2e2dSJohn Marino char *note_name = "LINUX";
9443cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9444cf7f2e2dSJohn Marino note_name, NT_S390_TODPREG, s390_todpreg, size);
9445cf7f2e2dSJohn Marino }
9446cf7f2e2dSJohn Marino
9447cf7f2e2dSJohn Marino char *
elfcore_write_s390_ctrs(bfd * abfd,char * buf,int * bufsiz,const void * s390_ctrs,int size)9448cf7f2e2dSJohn Marino elfcore_write_s390_ctrs (bfd *abfd,
9449cf7f2e2dSJohn Marino char *buf,
9450cf7f2e2dSJohn Marino int *bufsiz,
9451cf7f2e2dSJohn Marino const void *s390_ctrs,
9452cf7f2e2dSJohn Marino int size)
9453cf7f2e2dSJohn Marino {
9454cf7f2e2dSJohn Marino char *note_name = "LINUX";
9455cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9456cf7f2e2dSJohn Marino note_name, NT_S390_CTRS, s390_ctrs, size);
9457cf7f2e2dSJohn Marino }
9458cf7f2e2dSJohn Marino
9459cf7f2e2dSJohn Marino char *
elfcore_write_s390_prefix(bfd * abfd,char * buf,int * bufsiz,const void * s390_prefix,int size)9460cf7f2e2dSJohn Marino elfcore_write_s390_prefix (bfd *abfd,
9461cf7f2e2dSJohn Marino char *buf,
9462cf7f2e2dSJohn Marino int *bufsiz,
9463cf7f2e2dSJohn Marino const void *s390_prefix,
9464cf7f2e2dSJohn Marino int size)
9465cf7f2e2dSJohn Marino {
9466cf7f2e2dSJohn Marino char *note_name = "LINUX";
9467cf7f2e2dSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9468cf7f2e2dSJohn Marino note_name, NT_S390_PREFIX, s390_prefix, size);
9469cf7f2e2dSJohn Marino }
9470cf7f2e2dSJohn Marino
94715796c8dcSSimon Schubert char *
elfcore_write_s390_last_break(bfd * abfd,char * buf,int * bufsiz,const void * s390_last_break,int size)9472a45ae5f8SJohn Marino elfcore_write_s390_last_break (bfd *abfd,
9473a45ae5f8SJohn Marino char *buf,
9474a45ae5f8SJohn Marino int *bufsiz,
9475a45ae5f8SJohn Marino const void *s390_last_break,
9476a45ae5f8SJohn Marino int size)
9477a45ae5f8SJohn Marino {
9478a45ae5f8SJohn Marino char *note_name = "LINUX";
9479a45ae5f8SJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9480a45ae5f8SJohn Marino note_name, NT_S390_LAST_BREAK,
9481a45ae5f8SJohn Marino s390_last_break, size);
9482a45ae5f8SJohn Marino }
9483a45ae5f8SJohn Marino
9484a45ae5f8SJohn Marino char *
elfcore_write_s390_system_call(bfd * abfd,char * buf,int * bufsiz,const void * s390_system_call,int size)9485a45ae5f8SJohn Marino elfcore_write_s390_system_call (bfd *abfd,
9486a45ae5f8SJohn Marino char *buf,
9487a45ae5f8SJohn Marino int *bufsiz,
9488a45ae5f8SJohn Marino const void *s390_system_call,
9489a45ae5f8SJohn Marino int size)
9490a45ae5f8SJohn Marino {
9491a45ae5f8SJohn Marino char *note_name = "LINUX";
9492a45ae5f8SJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9493a45ae5f8SJohn Marino note_name, NT_S390_SYSTEM_CALL,
9494a45ae5f8SJohn Marino s390_system_call, size);
9495a45ae5f8SJohn Marino }
9496a45ae5f8SJohn Marino
9497a45ae5f8SJohn Marino char *
elfcore_write_s390_tdb(bfd * abfd,char * buf,int * bufsiz,const void * s390_tdb,int size)9498*ef5ccd6cSJohn Marino elfcore_write_s390_tdb (bfd *abfd,
9499*ef5ccd6cSJohn Marino char *buf,
9500*ef5ccd6cSJohn Marino int *bufsiz,
9501*ef5ccd6cSJohn Marino const void *s390_tdb,
9502*ef5ccd6cSJohn Marino int size)
9503*ef5ccd6cSJohn Marino {
9504*ef5ccd6cSJohn Marino char *note_name = "LINUX";
9505*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9506*ef5ccd6cSJohn Marino note_name, NT_S390_TDB, s390_tdb, size);
9507*ef5ccd6cSJohn Marino }
9508*ef5ccd6cSJohn Marino
9509*ef5ccd6cSJohn Marino char *
elfcore_write_arm_vfp(bfd * abfd,char * buf,int * bufsiz,const void * arm_vfp,int size)9510a45ae5f8SJohn Marino elfcore_write_arm_vfp (bfd *abfd,
9511a45ae5f8SJohn Marino char *buf,
9512a45ae5f8SJohn Marino int *bufsiz,
9513a45ae5f8SJohn Marino const void *arm_vfp,
9514a45ae5f8SJohn Marino int size)
9515a45ae5f8SJohn Marino {
9516a45ae5f8SJohn Marino char *note_name = "LINUX";
9517a45ae5f8SJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9518a45ae5f8SJohn Marino note_name, NT_ARM_VFP, arm_vfp, size);
9519a45ae5f8SJohn Marino }
9520a45ae5f8SJohn Marino
9521a45ae5f8SJohn Marino char *
elfcore_write_aarch_tls(bfd * abfd,char * buf,int * bufsiz,const void * aarch_tls,int size)9522*ef5ccd6cSJohn Marino elfcore_write_aarch_tls (bfd *abfd,
9523*ef5ccd6cSJohn Marino char *buf,
9524*ef5ccd6cSJohn Marino int *bufsiz,
9525*ef5ccd6cSJohn Marino const void *aarch_tls,
9526*ef5ccd6cSJohn Marino int size)
9527*ef5ccd6cSJohn Marino {
9528*ef5ccd6cSJohn Marino char *note_name = "LINUX";
9529*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9530*ef5ccd6cSJohn Marino note_name, NT_ARM_TLS, aarch_tls, size);
9531*ef5ccd6cSJohn Marino }
9532*ef5ccd6cSJohn Marino
9533*ef5ccd6cSJohn Marino char *
elfcore_write_aarch_hw_break(bfd * abfd,char * buf,int * bufsiz,const void * aarch_hw_break,int size)9534*ef5ccd6cSJohn Marino elfcore_write_aarch_hw_break (bfd *abfd,
9535*ef5ccd6cSJohn Marino char *buf,
9536*ef5ccd6cSJohn Marino int *bufsiz,
9537*ef5ccd6cSJohn Marino const void *aarch_hw_break,
9538*ef5ccd6cSJohn Marino int size)
9539*ef5ccd6cSJohn Marino {
9540*ef5ccd6cSJohn Marino char *note_name = "LINUX";
9541*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9542*ef5ccd6cSJohn Marino note_name, NT_ARM_HW_BREAK, aarch_hw_break, size);
9543*ef5ccd6cSJohn Marino }
9544*ef5ccd6cSJohn Marino
9545*ef5ccd6cSJohn Marino char *
elfcore_write_aarch_hw_watch(bfd * abfd,char * buf,int * bufsiz,const void * aarch_hw_watch,int size)9546*ef5ccd6cSJohn Marino elfcore_write_aarch_hw_watch (bfd *abfd,
9547*ef5ccd6cSJohn Marino char *buf,
9548*ef5ccd6cSJohn Marino int *bufsiz,
9549*ef5ccd6cSJohn Marino const void *aarch_hw_watch,
9550*ef5ccd6cSJohn Marino int size)
9551*ef5ccd6cSJohn Marino {
9552*ef5ccd6cSJohn Marino char *note_name = "LINUX";
9553*ef5ccd6cSJohn Marino return elfcore_write_note (abfd, buf, bufsiz,
9554*ef5ccd6cSJohn Marino note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size);
9555*ef5ccd6cSJohn Marino }
9556*ef5ccd6cSJohn Marino
9557*ef5ccd6cSJohn Marino char *
elfcore_write_register_note(bfd * abfd,char * buf,int * bufsiz,const char * section,const void * data,int size)95585796c8dcSSimon Schubert elfcore_write_register_note (bfd *abfd,
95595796c8dcSSimon Schubert char *buf,
95605796c8dcSSimon Schubert int *bufsiz,
95615796c8dcSSimon Schubert const char *section,
95625796c8dcSSimon Schubert const void *data,
95635796c8dcSSimon Schubert int size)
95645796c8dcSSimon Schubert {
95655796c8dcSSimon Schubert if (strcmp (section, ".reg2") == 0)
95665796c8dcSSimon Schubert return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
95675796c8dcSSimon Schubert if (strcmp (section, ".reg-xfp") == 0)
95685796c8dcSSimon Schubert return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
9569cf7f2e2dSJohn Marino if (strcmp (section, ".reg-xstate") == 0)
9570cf7f2e2dSJohn Marino return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size);
95715796c8dcSSimon Schubert if (strcmp (section, ".reg-ppc-vmx") == 0)
95725796c8dcSSimon Schubert return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
95735796c8dcSSimon Schubert if (strcmp (section, ".reg-ppc-vsx") == 0)
95745796c8dcSSimon Schubert return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
9575cf7f2e2dSJohn Marino if (strcmp (section, ".reg-s390-high-gprs") == 0)
9576cf7f2e2dSJohn Marino return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size);
9577cf7f2e2dSJohn Marino if (strcmp (section, ".reg-s390-timer") == 0)
9578cf7f2e2dSJohn Marino return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size);
9579cf7f2e2dSJohn Marino if (strcmp (section, ".reg-s390-todcmp") == 0)
9580cf7f2e2dSJohn Marino return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size);
9581cf7f2e2dSJohn Marino if (strcmp (section, ".reg-s390-todpreg") == 0)
9582cf7f2e2dSJohn Marino return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
9583cf7f2e2dSJohn Marino if (strcmp (section, ".reg-s390-ctrs") == 0)
9584cf7f2e2dSJohn Marino return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
9585cf7f2e2dSJohn Marino if (strcmp (section, ".reg-s390-prefix") == 0)
9586cf7f2e2dSJohn Marino return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
9587a45ae5f8SJohn Marino if (strcmp (section, ".reg-s390-last-break") == 0)
9588a45ae5f8SJohn Marino return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
9589a45ae5f8SJohn Marino if (strcmp (section, ".reg-s390-system-call") == 0)
9590a45ae5f8SJohn Marino return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
9591*ef5ccd6cSJohn Marino if (strcmp (section, ".reg-s390-tdb") == 0)
9592*ef5ccd6cSJohn Marino return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
9593a45ae5f8SJohn Marino if (strcmp (section, ".reg-arm-vfp") == 0)
9594a45ae5f8SJohn Marino return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
9595*ef5ccd6cSJohn Marino if (strcmp (section, ".reg-aarch-tls") == 0)
9596*ef5ccd6cSJohn Marino return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size);
9597*ef5ccd6cSJohn Marino if (strcmp (section, ".reg-aarch-hw-break") == 0)
9598*ef5ccd6cSJohn Marino return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size);
9599*ef5ccd6cSJohn Marino if (strcmp (section, ".reg-aarch-hw-watch") == 0)
9600*ef5ccd6cSJohn Marino return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size);
96015796c8dcSSimon Schubert return NULL;
96025796c8dcSSimon Schubert }
96035796c8dcSSimon Schubert
96045796c8dcSSimon Schubert static bfd_boolean
elf_parse_notes(bfd * abfd,char * buf,size_t size,file_ptr offset)96055796c8dcSSimon Schubert elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
96065796c8dcSSimon Schubert {
96075796c8dcSSimon Schubert char *p;
96085796c8dcSSimon Schubert
96095796c8dcSSimon Schubert p = buf;
96105796c8dcSSimon Schubert while (p < buf + size)
96115796c8dcSSimon Schubert {
96125796c8dcSSimon Schubert /* FIXME: bad alignment assumption. */
96135796c8dcSSimon Schubert Elf_External_Note *xnp = (Elf_External_Note *) p;
96145796c8dcSSimon Schubert Elf_Internal_Note in;
96155796c8dcSSimon Schubert
96165796c8dcSSimon Schubert if (offsetof (Elf_External_Note, name) > buf - p + size)
96175796c8dcSSimon Schubert return FALSE;
96185796c8dcSSimon Schubert
96195796c8dcSSimon Schubert in.type = H_GET_32 (abfd, xnp->type);
96205796c8dcSSimon Schubert
96215796c8dcSSimon Schubert in.namesz = H_GET_32 (abfd, xnp->namesz);
96225796c8dcSSimon Schubert in.namedata = xnp->name;
96235796c8dcSSimon Schubert if (in.namesz > buf - in.namedata + size)
96245796c8dcSSimon Schubert return FALSE;
96255796c8dcSSimon Schubert
96265796c8dcSSimon Schubert in.descsz = H_GET_32 (abfd, xnp->descsz);
96275796c8dcSSimon Schubert in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
96285796c8dcSSimon Schubert in.descpos = offset + (in.descdata - buf);
96295796c8dcSSimon Schubert if (in.descsz != 0
96305796c8dcSSimon Schubert && (in.descdata >= buf + size
96315796c8dcSSimon Schubert || in.descsz > buf - in.descdata + size))
96325796c8dcSSimon Schubert return FALSE;
96335796c8dcSSimon Schubert
96345796c8dcSSimon Schubert switch (bfd_get_format (abfd))
96355796c8dcSSimon Schubert {
96365796c8dcSSimon Schubert default:
96375796c8dcSSimon Schubert return TRUE;
96385796c8dcSSimon Schubert
96395796c8dcSSimon Schubert case bfd_core:
96405796c8dcSSimon Schubert if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
96415796c8dcSSimon Schubert {
96425796c8dcSSimon Schubert if (! elfcore_grok_netbsd_note (abfd, &in))
96435796c8dcSSimon Schubert return FALSE;
96445796c8dcSSimon Schubert }
96455796c8dcSSimon Schubert else if (CONST_STRNEQ (in.namedata, "OpenBSD"))
96465796c8dcSSimon Schubert {
96475796c8dcSSimon Schubert if (! elfcore_grok_openbsd_note (abfd, &in))
96485796c8dcSSimon Schubert return FALSE;
96495796c8dcSSimon Schubert }
96505796c8dcSSimon Schubert else if (CONST_STRNEQ (in.namedata, "QNX"))
96515796c8dcSSimon Schubert {
96525796c8dcSSimon Schubert if (! elfcore_grok_nto_note (abfd, &in))
96535796c8dcSSimon Schubert return FALSE;
96545796c8dcSSimon Schubert }
96555796c8dcSSimon Schubert else if (CONST_STRNEQ (in.namedata, "SPU/"))
96565796c8dcSSimon Schubert {
96575796c8dcSSimon Schubert if (! elfcore_grok_spu_note (abfd, &in))
96585796c8dcSSimon Schubert return FALSE;
96595796c8dcSSimon Schubert }
96605796c8dcSSimon Schubert else
96615796c8dcSSimon Schubert {
96625796c8dcSSimon Schubert if (! elfcore_grok_note (abfd, &in))
96635796c8dcSSimon Schubert return FALSE;
96645796c8dcSSimon Schubert }
96655796c8dcSSimon Schubert break;
96665796c8dcSSimon Schubert
96675796c8dcSSimon Schubert case bfd_object:
96685796c8dcSSimon Schubert if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
96695796c8dcSSimon Schubert {
96705796c8dcSSimon Schubert if (! elfobj_grok_gnu_note (abfd, &in))
96715796c8dcSSimon Schubert return FALSE;
96725796c8dcSSimon Schubert }
9673a45ae5f8SJohn Marino else if (in.namesz == sizeof "stapsdt"
9674a45ae5f8SJohn Marino && strcmp (in.namedata, "stapsdt") == 0)
9675a45ae5f8SJohn Marino {
9676a45ae5f8SJohn Marino if (! elfobj_grok_stapsdt_note (abfd, &in))
9677a45ae5f8SJohn Marino return FALSE;
9678a45ae5f8SJohn Marino }
96795796c8dcSSimon Schubert break;
96805796c8dcSSimon Schubert }
96815796c8dcSSimon Schubert
96825796c8dcSSimon Schubert p = in.descdata + BFD_ALIGN (in.descsz, 4);
96835796c8dcSSimon Schubert }
96845796c8dcSSimon Schubert
96855796c8dcSSimon Schubert return TRUE;
96865796c8dcSSimon Schubert }
96875796c8dcSSimon Schubert
96885796c8dcSSimon Schubert static bfd_boolean
elf_read_notes(bfd * abfd,file_ptr offset,bfd_size_type size)96895796c8dcSSimon Schubert elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
96905796c8dcSSimon Schubert {
96915796c8dcSSimon Schubert char *buf;
96925796c8dcSSimon Schubert
96935796c8dcSSimon Schubert if (size <= 0)
96945796c8dcSSimon Schubert return TRUE;
96955796c8dcSSimon Schubert
96965796c8dcSSimon Schubert if (bfd_seek (abfd, offset, SEEK_SET) != 0)
96975796c8dcSSimon Schubert return FALSE;
96985796c8dcSSimon Schubert
96995796c8dcSSimon Schubert buf = (char *) bfd_malloc (size);
97005796c8dcSSimon Schubert if (buf == NULL)
97015796c8dcSSimon Schubert return FALSE;
97025796c8dcSSimon Schubert
97035796c8dcSSimon Schubert if (bfd_bread (buf, size, abfd) != size
97045796c8dcSSimon Schubert || !elf_parse_notes (abfd, buf, size, offset))
97055796c8dcSSimon Schubert {
97065796c8dcSSimon Schubert free (buf);
97075796c8dcSSimon Schubert return FALSE;
97085796c8dcSSimon Schubert }
97095796c8dcSSimon Schubert
97105796c8dcSSimon Schubert free (buf);
97115796c8dcSSimon Schubert return TRUE;
97125796c8dcSSimon Schubert }
97135796c8dcSSimon Schubert
97145796c8dcSSimon Schubert /* Providing external access to the ELF program header table. */
97155796c8dcSSimon Schubert
97165796c8dcSSimon Schubert /* Return an upper bound on the number of bytes required to store a
97175796c8dcSSimon Schubert copy of ABFD's program header table entries. Return -1 if an error
97185796c8dcSSimon Schubert occurs; bfd_get_error will return an appropriate code. */
97195796c8dcSSimon Schubert
97205796c8dcSSimon Schubert long
bfd_get_elf_phdr_upper_bound(bfd * abfd)97215796c8dcSSimon Schubert bfd_get_elf_phdr_upper_bound (bfd *abfd)
97225796c8dcSSimon Schubert {
97235796c8dcSSimon Schubert if (abfd->xvec->flavour != bfd_target_elf_flavour)
97245796c8dcSSimon Schubert {
97255796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
97265796c8dcSSimon Schubert return -1;
97275796c8dcSSimon Schubert }
97285796c8dcSSimon Schubert
97295796c8dcSSimon Schubert return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
97305796c8dcSSimon Schubert }
97315796c8dcSSimon Schubert
97325796c8dcSSimon Schubert /* Copy ABFD's program header table entries to *PHDRS. The entries
97335796c8dcSSimon Schubert will be stored as an array of Elf_Internal_Phdr structures, as
97345796c8dcSSimon Schubert defined in include/elf/internal.h. To find out how large the
97355796c8dcSSimon Schubert buffer needs to be, call bfd_get_elf_phdr_upper_bound.
97365796c8dcSSimon Schubert
97375796c8dcSSimon Schubert Return the number of program header table entries read, or -1 if an
97385796c8dcSSimon Schubert error occurs; bfd_get_error will return an appropriate code. */
97395796c8dcSSimon Schubert
97405796c8dcSSimon Schubert int
bfd_get_elf_phdrs(bfd * abfd,void * phdrs)97415796c8dcSSimon Schubert bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
97425796c8dcSSimon Schubert {
97435796c8dcSSimon Schubert int num_phdrs;
97445796c8dcSSimon Schubert
97455796c8dcSSimon Schubert if (abfd->xvec->flavour != bfd_target_elf_flavour)
97465796c8dcSSimon Schubert {
97475796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
97485796c8dcSSimon Schubert return -1;
97495796c8dcSSimon Schubert }
97505796c8dcSSimon Schubert
97515796c8dcSSimon Schubert num_phdrs = elf_elfheader (abfd)->e_phnum;
97525796c8dcSSimon Schubert memcpy (phdrs, elf_tdata (abfd)->phdr,
97535796c8dcSSimon Schubert num_phdrs * sizeof (Elf_Internal_Phdr));
97545796c8dcSSimon Schubert
97555796c8dcSSimon Schubert return num_phdrs;
97565796c8dcSSimon Schubert }
97575796c8dcSSimon Schubert
97585796c8dcSSimon Schubert enum elf_reloc_type_class
_bfd_elf_reloc_type_class(const Elf_Internal_Rela * rela ATTRIBUTE_UNUSED)97595796c8dcSSimon Schubert _bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
97605796c8dcSSimon Schubert {
97615796c8dcSSimon Schubert return reloc_class_normal;
97625796c8dcSSimon Schubert }
97635796c8dcSSimon Schubert
97645796c8dcSSimon Schubert /* For RELA architectures, return the relocation value for a
97655796c8dcSSimon Schubert relocation against a local symbol. */
97665796c8dcSSimon Schubert
97675796c8dcSSimon Schubert bfd_vma
_bfd_elf_rela_local_sym(bfd * abfd,Elf_Internal_Sym * sym,asection ** psec,Elf_Internal_Rela * rel)97685796c8dcSSimon Schubert _bfd_elf_rela_local_sym (bfd *abfd,
97695796c8dcSSimon Schubert Elf_Internal_Sym *sym,
97705796c8dcSSimon Schubert asection **psec,
97715796c8dcSSimon Schubert Elf_Internal_Rela *rel)
97725796c8dcSSimon Schubert {
97735796c8dcSSimon Schubert asection *sec = *psec;
97745796c8dcSSimon Schubert bfd_vma relocation;
97755796c8dcSSimon Schubert
97765796c8dcSSimon Schubert relocation = (sec->output_section->vma
97775796c8dcSSimon Schubert + sec->output_offset
97785796c8dcSSimon Schubert + sym->st_value);
97795796c8dcSSimon Schubert if ((sec->flags & SEC_MERGE)
97805796c8dcSSimon Schubert && ELF_ST_TYPE (sym->st_info) == STT_SECTION
9781*ef5ccd6cSJohn Marino && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
97825796c8dcSSimon Schubert {
97835796c8dcSSimon Schubert rel->r_addend =
97845796c8dcSSimon Schubert _bfd_merged_section_offset (abfd, psec,
97855796c8dcSSimon Schubert elf_section_data (sec)->sec_info,
97865796c8dcSSimon Schubert sym->st_value + rel->r_addend);
97875796c8dcSSimon Schubert if (sec != *psec)
97885796c8dcSSimon Schubert {
97895796c8dcSSimon Schubert /* If we have changed the section, and our original section is
97905796c8dcSSimon Schubert marked with SEC_EXCLUDE, it means that the original
97915796c8dcSSimon Schubert SEC_MERGE section has been completely subsumed in some
97925796c8dcSSimon Schubert other SEC_MERGE section. In this case, we need to leave
97935796c8dcSSimon Schubert some info around for --emit-relocs. */
97945796c8dcSSimon Schubert if ((sec->flags & SEC_EXCLUDE) != 0)
97955796c8dcSSimon Schubert sec->kept_section = *psec;
97965796c8dcSSimon Schubert sec = *psec;
97975796c8dcSSimon Schubert }
97985796c8dcSSimon Schubert rel->r_addend -= relocation;
97995796c8dcSSimon Schubert rel->r_addend += sec->output_section->vma + sec->output_offset;
98005796c8dcSSimon Schubert }
98015796c8dcSSimon Schubert return relocation;
98025796c8dcSSimon Schubert }
98035796c8dcSSimon Schubert
98045796c8dcSSimon Schubert bfd_vma
_bfd_elf_rel_local_sym(bfd * abfd,Elf_Internal_Sym * sym,asection ** psec,bfd_vma addend)98055796c8dcSSimon Schubert _bfd_elf_rel_local_sym (bfd *abfd,
98065796c8dcSSimon Schubert Elf_Internal_Sym *sym,
98075796c8dcSSimon Schubert asection **psec,
98085796c8dcSSimon Schubert bfd_vma addend)
98095796c8dcSSimon Schubert {
98105796c8dcSSimon Schubert asection *sec = *psec;
98115796c8dcSSimon Schubert
9812*ef5ccd6cSJohn Marino if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
98135796c8dcSSimon Schubert return sym->st_value + addend;
98145796c8dcSSimon Schubert
98155796c8dcSSimon Schubert return _bfd_merged_section_offset (abfd, psec,
98165796c8dcSSimon Schubert elf_section_data (sec)->sec_info,
98175796c8dcSSimon Schubert sym->st_value + addend);
98185796c8dcSSimon Schubert }
98195796c8dcSSimon Schubert
98205796c8dcSSimon Schubert bfd_vma
_bfd_elf_section_offset(bfd * abfd,struct bfd_link_info * info,asection * sec,bfd_vma offset)98215796c8dcSSimon Schubert _bfd_elf_section_offset (bfd *abfd,
98225796c8dcSSimon Schubert struct bfd_link_info *info,
98235796c8dcSSimon Schubert asection *sec,
98245796c8dcSSimon Schubert bfd_vma offset)
98255796c8dcSSimon Schubert {
98265796c8dcSSimon Schubert switch (sec->sec_info_type)
98275796c8dcSSimon Schubert {
9828*ef5ccd6cSJohn Marino case SEC_INFO_TYPE_STABS:
98295796c8dcSSimon Schubert return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
98305796c8dcSSimon Schubert offset);
9831*ef5ccd6cSJohn Marino case SEC_INFO_TYPE_EH_FRAME:
98325796c8dcSSimon Schubert return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
98335796c8dcSSimon Schubert default:
9834a45ae5f8SJohn Marino if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
9835a45ae5f8SJohn Marino {
9836a45ae5f8SJohn Marino const struct elf_backend_data *bed = get_elf_backend_data (abfd);
9837a45ae5f8SJohn Marino bfd_size_type address_size = bed->s->arch_size / 8;
9838a45ae5f8SJohn Marino offset = sec->size - offset - address_size;
9839a45ae5f8SJohn Marino }
98405796c8dcSSimon Schubert return offset;
98415796c8dcSSimon Schubert }
98425796c8dcSSimon Schubert }
98435796c8dcSSimon Schubert
98445796c8dcSSimon Schubert /* Create a new BFD as if by bfd_openr. Rather than opening a file,
98455796c8dcSSimon Schubert reconstruct an ELF file by reading the segments out of remote memory
98465796c8dcSSimon Schubert based on the ELF file header at EHDR_VMA and the ELF program headers it
98475796c8dcSSimon Schubert points to. If not null, *LOADBASEP is filled in with the difference
98485796c8dcSSimon Schubert between the VMAs from which the segments were read, and the VMAs the
98495796c8dcSSimon Schubert file headers (and hence BFD's idea of each section's VMA) put them at.
98505796c8dcSSimon Schubert
98515796c8dcSSimon Schubert The function TARGET_READ_MEMORY is called to copy LEN bytes from the
98525796c8dcSSimon Schubert remote memory at target address VMA into the local buffer at MYADDR; it
98535796c8dcSSimon Schubert should return zero on success or an `errno' code on failure. TEMPL must
98545796c8dcSSimon Schubert be a BFD for an ELF target with the word size and byte order found in
98555796c8dcSSimon Schubert the remote memory. */
98565796c8dcSSimon Schubert
98575796c8dcSSimon Schubert bfd *
bfd_elf_bfd_from_remote_memory(bfd * templ,bfd_vma ehdr_vma,bfd_vma * loadbasep,int (* target_read_memory)(bfd_vma,bfd_byte *,bfd_size_type))98585796c8dcSSimon Schubert bfd_elf_bfd_from_remote_memory
98595796c8dcSSimon Schubert (bfd *templ,
98605796c8dcSSimon Schubert bfd_vma ehdr_vma,
98615796c8dcSSimon Schubert bfd_vma *loadbasep,
9862*ef5ccd6cSJohn Marino int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
98635796c8dcSSimon Schubert {
98645796c8dcSSimon Schubert return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
98655796c8dcSSimon Schubert (templ, ehdr_vma, loadbasep, target_read_memory);
98665796c8dcSSimon Schubert }
98675796c8dcSSimon Schubert
98685796c8dcSSimon Schubert long
_bfd_elf_get_synthetic_symtab(bfd * abfd,long symcount ATTRIBUTE_UNUSED,asymbol ** syms ATTRIBUTE_UNUSED,long dynsymcount,asymbol ** dynsyms,asymbol ** ret)98695796c8dcSSimon Schubert _bfd_elf_get_synthetic_symtab (bfd *abfd,
98705796c8dcSSimon Schubert long symcount ATTRIBUTE_UNUSED,
98715796c8dcSSimon Schubert asymbol **syms ATTRIBUTE_UNUSED,
98725796c8dcSSimon Schubert long dynsymcount,
98735796c8dcSSimon Schubert asymbol **dynsyms,
98745796c8dcSSimon Schubert asymbol **ret)
98755796c8dcSSimon Schubert {
98765796c8dcSSimon Schubert const struct elf_backend_data *bed = get_elf_backend_data (abfd);
98775796c8dcSSimon Schubert asection *relplt;
98785796c8dcSSimon Schubert asymbol *s;
98795796c8dcSSimon Schubert const char *relplt_name;
98805796c8dcSSimon Schubert bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
98815796c8dcSSimon Schubert arelent *p;
98825796c8dcSSimon Schubert long count, i, n;
98835796c8dcSSimon Schubert size_t size;
98845796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
98855796c8dcSSimon Schubert char *names;
98865796c8dcSSimon Schubert asection *plt;
98875796c8dcSSimon Schubert
98885796c8dcSSimon Schubert *ret = NULL;
98895796c8dcSSimon Schubert
98905796c8dcSSimon Schubert if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
98915796c8dcSSimon Schubert return 0;
98925796c8dcSSimon Schubert
98935796c8dcSSimon Schubert if (dynsymcount <= 0)
98945796c8dcSSimon Schubert return 0;
98955796c8dcSSimon Schubert
98965796c8dcSSimon Schubert if (!bed->plt_sym_val)
98975796c8dcSSimon Schubert return 0;
98985796c8dcSSimon Schubert
98995796c8dcSSimon Schubert relplt_name = bed->relplt_name;
99005796c8dcSSimon Schubert if (relplt_name == NULL)
99015796c8dcSSimon Schubert relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
99025796c8dcSSimon Schubert relplt = bfd_get_section_by_name (abfd, relplt_name);
99035796c8dcSSimon Schubert if (relplt == NULL)
99045796c8dcSSimon Schubert return 0;
99055796c8dcSSimon Schubert
99065796c8dcSSimon Schubert hdr = &elf_section_data (relplt)->this_hdr;
99075796c8dcSSimon Schubert if (hdr->sh_link != elf_dynsymtab (abfd)
99085796c8dcSSimon Schubert || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
99095796c8dcSSimon Schubert return 0;
99105796c8dcSSimon Schubert
99115796c8dcSSimon Schubert plt = bfd_get_section_by_name (abfd, ".plt");
99125796c8dcSSimon Schubert if (plt == NULL)
99135796c8dcSSimon Schubert return 0;
99145796c8dcSSimon Schubert
99155796c8dcSSimon Schubert slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
99165796c8dcSSimon Schubert if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
99175796c8dcSSimon Schubert return -1;
99185796c8dcSSimon Schubert
99195796c8dcSSimon Schubert count = relplt->size / hdr->sh_entsize;
99205796c8dcSSimon Schubert size = count * sizeof (asymbol);
99215796c8dcSSimon Schubert p = relplt->relocation;
99225796c8dcSSimon Schubert for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
99235796c8dcSSimon Schubert {
99245796c8dcSSimon Schubert size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
99255796c8dcSSimon Schubert if (p->addend != 0)
99265796c8dcSSimon Schubert {
99275796c8dcSSimon Schubert #ifdef BFD64
99285796c8dcSSimon Schubert size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
99295796c8dcSSimon Schubert #else
99305796c8dcSSimon Schubert size += sizeof ("+0x") - 1 + 8;
99315796c8dcSSimon Schubert #endif
99325796c8dcSSimon Schubert }
99335796c8dcSSimon Schubert }
99345796c8dcSSimon Schubert
99355796c8dcSSimon Schubert s = *ret = (asymbol *) bfd_malloc (size);
99365796c8dcSSimon Schubert if (s == NULL)
99375796c8dcSSimon Schubert return -1;
99385796c8dcSSimon Schubert
99395796c8dcSSimon Schubert names = (char *) (s + count);
99405796c8dcSSimon Schubert p = relplt->relocation;
99415796c8dcSSimon Schubert n = 0;
99425796c8dcSSimon Schubert for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
99435796c8dcSSimon Schubert {
99445796c8dcSSimon Schubert size_t len;
99455796c8dcSSimon Schubert bfd_vma addr;
99465796c8dcSSimon Schubert
99475796c8dcSSimon Schubert addr = bed->plt_sym_val (i, plt, p);
99485796c8dcSSimon Schubert if (addr == (bfd_vma) -1)
99495796c8dcSSimon Schubert continue;
99505796c8dcSSimon Schubert
99515796c8dcSSimon Schubert *s = **p->sym_ptr_ptr;
99525796c8dcSSimon Schubert /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
99535796c8dcSSimon Schubert we are defining a symbol, ensure one of them is set. */
99545796c8dcSSimon Schubert if ((s->flags & BSF_LOCAL) == 0)
99555796c8dcSSimon Schubert s->flags |= BSF_GLOBAL;
99565796c8dcSSimon Schubert s->flags |= BSF_SYNTHETIC;
99575796c8dcSSimon Schubert s->section = plt;
99585796c8dcSSimon Schubert s->value = addr - plt->vma;
99595796c8dcSSimon Schubert s->name = names;
99605796c8dcSSimon Schubert s->udata.p = NULL;
99615796c8dcSSimon Schubert len = strlen ((*p->sym_ptr_ptr)->name);
99625796c8dcSSimon Schubert memcpy (names, (*p->sym_ptr_ptr)->name, len);
99635796c8dcSSimon Schubert names += len;
99645796c8dcSSimon Schubert if (p->addend != 0)
99655796c8dcSSimon Schubert {
99665796c8dcSSimon Schubert char buf[30], *a;
9967cf7f2e2dSJohn Marino
99685796c8dcSSimon Schubert memcpy (names, "+0x", sizeof ("+0x") - 1);
99695796c8dcSSimon Schubert names += sizeof ("+0x") - 1;
99705796c8dcSSimon Schubert bfd_sprintf_vma (abfd, buf, p->addend);
99715796c8dcSSimon Schubert for (a = buf; *a == '0'; ++a)
99725796c8dcSSimon Schubert ;
99735796c8dcSSimon Schubert len = strlen (a);
99745796c8dcSSimon Schubert memcpy (names, a, len);
99755796c8dcSSimon Schubert names += len;
99765796c8dcSSimon Schubert }
99775796c8dcSSimon Schubert memcpy (names, "@plt", sizeof ("@plt"));
99785796c8dcSSimon Schubert names += sizeof ("@plt");
99795796c8dcSSimon Schubert ++s, ++n;
99805796c8dcSSimon Schubert }
99815796c8dcSSimon Schubert
99825796c8dcSSimon Schubert return n;
99835796c8dcSSimon Schubert }
99845796c8dcSSimon Schubert
99855796c8dcSSimon Schubert /* It is only used by x86-64 so far. */
99865796c8dcSSimon Schubert asection _bfd_elf_large_com_section
99875796c8dcSSimon Schubert = BFD_FAKE_SECTION (_bfd_elf_large_com_section,
99885796c8dcSSimon Schubert SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
99895796c8dcSSimon Schubert
99905796c8dcSSimon Schubert void
_bfd_elf_set_osabi(bfd * abfd,struct bfd_link_info * link_info ATTRIBUTE_UNUSED)99915796c8dcSSimon Schubert _bfd_elf_set_osabi (bfd * abfd,
99925796c8dcSSimon Schubert struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
99935796c8dcSSimon Schubert {
99945796c8dcSSimon Schubert Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
99955796c8dcSSimon Schubert
99965796c8dcSSimon Schubert i_ehdrp = elf_elfheader (abfd);
99975796c8dcSSimon Schubert
99985796c8dcSSimon Schubert i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
99995796c8dcSSimon Schubert
100005796c8dcSSimon Schubert /* To make things simpler for the loader on Linux systems we set the
10001a45ae5f8SJohn Marino osabi field to ELFOSABI_GNU if the binary contains symbols of
10002a45ae5f8SJohn Marino the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding. */
100035796c8dcSSimon Schubert if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
10004a45ae5f8SJohn Marino && elf_tdata (abfd)->has_gnu_symbols)
10005a45ae5f8SJohn Marino i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
100065796c8dcSSimon Schubert }
100075796c8dcSSimon Schubert
100085796c8dcSSimon Schubert
100095796c8dcSSimon Schubert /* Return TRUE for ELF symbol types that represent functions.
100105796c8dcSSimon Schubert This is the default version of this function, which is sufficient for
100115796c8dcSSimon Schubert most targets. It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC. */
100125796c8dcSSimon Schubert
100135796c8dcSSimon Schubert bfd_boolean
_bfd_elf_is_function_type(unsigned int type)100145796c8dcSSimon Schubert _bfd_elf_is_function_type (unsigned int type)
100155796c8dcSSimon Schubert {
100165796c8dcSSimon Schubert return (type == STT_FUNC
100175796c8dcSSimon Schubert || type == STT_GNU_IFUNC);
100185796c8dcSSimon Schubert }
10019*ef5ccd6cSJohn Marino
10020*ef5ccd6cSJohn Marino /* If the ELF symbol SYM might be a function in SEC, return the
10021*ef5ccd6cSJohn Marino function size and set *CODE_OFF to the function's entry point,
10022*ef5ccd6cSJohn Marino otherwise return zero. */
10023*ef5ccd6cSJohn Marino
10024*ef5ccd6cSJohn Marino bfd_size_type
_bfd_elf_maybe_function_sym(const asymbol * sym,asection * sec,bfd_vma * code_off)10025*ef5ccd6cSJohn Marino _bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
10026*ef5ccd6cSJohn Marino bfd_vma *code_off)
10027*ef5ccd6cSJohn Marino {
10028*ef5ccd6cSJohn Marino bfd_size_type size;
10029*ef5ccd6cSJohn Marino
10030*ef5ccd6cSJohn Marino if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
10031*ef5ccd6cSJohn Marino | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
10032*ef5ccd6cSJohn Marino || sym->section != sec)
10033*ef5ccd6cSJohn Marino return 0;
10034*ef5ccd6cSJohn Marino
10035*ef5ccd6cSJohn Marino *code_off = sym->value;
10036*ef5ccd6cSJohn Marino size = 0;
10037*ef5ccd6cSJohn Marino if (!(sym->flags & BSF_SYNTHETIC))
10038*ef5ccd6cSJohn Marino size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
10039*ef5ccd6cSJohn Marino if (size == 0)
10040*ef5ccd6cSJohn Marino size = 1;
10041*ef5ccd6cSJohn Marino return size;
10042*ef5ccd6cSJohn Marino }
10043