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