Home | History | Annotate | Line # | Download | only in ld
ldelfgen.c revision 1.1.1.1
      1 /* Emulation code used by all ELF targets.
      2    Copyright (C) 1991-2020 Free Software Foundation, Inc.
      3 
      4    This file is part of the GNU Binutils.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "bfdlink.h"
     24 #include "ctf-api.h"
     25 #include "ld.h"
     26 #include "ldmain.h"
     27 #include "ldmisc.h"
     28 #include "ldexp.h"
     29 #include "ldlang.h"
     30 #include "elf-bfd.h"
     31 #include "ldelfgen.h"
     32 
     33 void
     34 ldelf_map_segments (bfd_boolean need_layout)
     35 {
     36   int tries = 10;
     37 
     38   do
     39     {
     40       lang_relax_sections (need_layout);
     41       need_layout = FALSE;
     42 
     43       if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour
     44 	  && !bfd_link_relocatable (&link_info))
     45 	{
     46 	  bfd_size_type phdr_size;
     47 
     48 	  phdr_size = elf_program_header_size (link_info.output_bfd);
     49 	  /* If we don't have user supplied phdrs, throw away any
     50 	     previous linker generated program headers.  */
     51 	  if (lang_phdr_list == NULL)
     52 	    elf_seg_map (link_info.output_bfd) = NULL;
     53 	  if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
     54 						  &link_info))
     55 	    einfo (_("%F%P: map sections to segments failed: %E\n"));
     56 
     57 	  if (phdr_size != elf_program_header_size (link_info.output_bfd))
     58 	    {
     59 	      if (tries > 6)
     60 		/* The first few times we allow any change to
     61 		   phdr_size .  */
     62 		need_layout = TRUE;
     63 	      else if (phdr_size
     64 		       < elf_program_header_size (link_info.output_bfd))
     65 		/* After that we only allow the size to grow.  */
     66 		need_layout = TRUE;
     67 	      else
     68 		elf_program_header_size (link_info.output_bfd) = phdr_size;
     69 	    }
     70 	}
     71     }
     72   while (need_layout && --tries);
     73 
     74   if (tries == 0)
     75     einfo (_("%F%P: looping in map_segments"));
     76 }
     77 
     78 /* We want to emit CTF early if and only if we are not targetting ELF with this
     79    invocation.  */
     80 
     81 int
     82 ldelf_emit_ctf_early (void)
     83 {
     84   if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
     85     return 0;
     86   return 1;
     87 }
     88 
     89 /* Callbacks used to map from bfd types to libctf types, under libctf's
     90    control.  */
     91 
     92 struct ctf_strsym_iter_cb_arg
     93 {
     94   struct elf_sym_strtab *syms;
     95   bfd_size_type symcount;
     96   struct elf_strtab_hash *symstrtab;
     97   size_t next_i;
     98   size_t next_idx;
     99 };
    100 
    101 /* Return strings from the strtab to libctf, one by one.  Returns NULL when
    102    iteration is complete.  */
    103 
    104 static const char *
    105 ldelf_ctf_strtab_iter_cb (uint32_t *offset, void *arg_)
    106 {
    107   bfd_size_type off;
    108   const char *ret;
    109 
    110   struct ctf_strsym_iter_cb_arg *arg =
    111     (struct ctf_strsym_iter_cb_arg *) arg_;
    112 
    113   /* There is no zeroth string.  */
    114   if (arg->next_i == 0)
    115     arg->next_i = 1;
    116 
    117   if (arg->next_i >= _bfd_elf_strtab_len (arg->symstrtab))
    118     {
    119       arg->next_i = 0;
    120       return NULL;
    121     }
    122 
    123   ret = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i++, &off);
    124   *offset = off;
    125 
    126   /* If we've overflowed, we cannot share any further strings: the CTF
    127      format cannot encode strings with such high offsets.  */
    128   if (*offset != off)
    129     return NULL;
    130 
    131   return ret;
    132 }
    133 
    134 /* Return symbols from the symbol table to libctf, one by one.  We assume (and
    135    assert) that the symbols in the elf_link_hash_table are in strictly ascending
    136    order, and that none will be added in between existing ones.  Returns NULL
    137    when iteration is complete.  */
    138 
    139 static struct ctf_link_sym *
    140 ldelf_ctf_symbols_iter_cb (struct ctf_link_sym *dest,
    141 					   void *arg_)
    142 {
    143   struct ctf_strsym_iter_cb_arg *arg =
    144     (struct ctf_strsym_iter_cb_arg *) arg_;
    145 
    146   if (arg->next_i > arg->symcount)
    147     {
    148       arg->next_i = 0;
    149       arg->next_idx = 0;
    150       return NULL;
    151     }
    152 
    153   ASSERT (arg->syms[arg->next_i].dest_index == arg->next_idx);
    154   dest->st_name = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i, NULL);
    155   dest->st_shndx = arg->syms[arg->next_i].sym.st_shndx;
    156   dest->st_type = ELF_ST_TYPE (arg->syms[arg->next_i].sym.st_info);
    157   dest->st_value = arg->syms[arg->next_i].sym.st_value;
    158   arg->next_i++;
    159   return dest;
    160 }
    161 
    162 void
    163 ldelf_examine_strtab_for_ctf
    164   (struct ctf_file *ctf_output, struct elf_sym_strtab *syms,
    165    bfd_size_type symcount, struct elf_strtab_hash *symstrtab)
    166 {
    167   struct ctf_strsym_iter_cb_arg args = { syms, symcount, symstrtab,
    168 					  0, 0 };
    169    if (!ctf_output)
    170      return;
    171 
    172    if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
    173        && !bfd_link_relocatable (&link_info))
    174     {
    175       if (ctf_link_add_strtab (ctf_output, ldelf_ctf_strtab_iter_cb,
    176 			       &args) < 0)
    177 	einfo (_("%F%P: warning: CTF strtab association failed; strings will "
    178 		 "not be shared: %s\n"),
    179 	       ctf_errmsg (ctf_errno (ctf_output)));
    180 
    181       if (ctf_link_shuffle_syms (ctf_output, ldelf_ctf_symbols_iter_cb,
    182 				 &args) < 0)
    183 	einfo (_("%F%P: warning: CTF symbol shuffling failed; slight space "
    184 		 "cost: %s\n"), ctf_errmsg (ctf_errno (ctf_output)));
    185     }
    186 }
    187