(root)/
binutils-2.41/
ld/
ldwrite.c
       1  /* ldwrite.c -- write out the linked file
       2     Copyright (C) 1991-2023 Free Software Foundation, Inc.
       3     Written by Steve Chamberlain sac@cygnus.com
       4  
       5     This file is part of the GNU Binutils.
       6  
       7     This program is free software; you can redistribute it and/or modify
       8     it under the terms of the GNU General Public License as published by
       9     the Free Software Foundation; either version 3 of the License, or
      10     (at your option) any later version.
      11  
      12     This program is distributed in the hope that it will be useful,
      13     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15     GNU General Public License for more details.
      16  
      17     You should have received a copy of the GNU General Public License
      18     along with this program; if not, write to the Free Software
      19     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
      20     MA 02110-1301, USA.  */
      21  
      22  #include "sysdep.h"
      23  #include "bfd.h"
      24  #include "bfdlink.h"
      25  #include "libiberty.h"
      26  #include "ctf-api.h"
      27  #include "safe-ctype.h"
      28  
      29  #include "ld.h"
      30  #include "ldexp.h"
      31  #include "ldlang.h"
      32  #include "ldwrite.h"
      33  #include "ldmisc.h"
      34  #include <ldgram.h>
      35  #include "ldmain.h"
      36  
      37  /* Build link_order structures for the BFD linker.  */
      38  
      39  static void
      40  build_link_order (lang_statement_union_type *statement)
      41  {
      42    switch (statement->header.type)
      43      {
      44      case lang_data_statement_enum:
      45        {
      46  	asection *output_section;
      47  	struct bfd_link_order *link_order;
      48  	bfd_vma value;
      49  
      50  	output_section = statement->data_statement.output_section;
      51  	ASSERT (output_section->owner == link_info.output_bfd);
      52  
      53  	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
      54  	      || ((output_section->flags & SEC_LOAD) != 0
      55  		  && (output_section->flags & SEC_THREAD_LOCAL))))
      56  	  break;
      57  
      58  	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
      59  	if (link_order == NULL)
      60  	  einfo (_("%F%P: bfd_new_link_order failed\n"));
      61  
      62  	link_order->type = bfd_data_link_order;
      63  	link_order->offset = statement->data_statement.output_offset;
      64  	link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
      65  
      66  	value = statement->data_statement.value;
      67  
      68  	/* By convention, the bfd_put routines for an unknown
      69  	   endianness are big endian, so we must swap here if the
      70  	   input is little endian.  */
      71  	if (!bfd_big_endian (link_info.output_bfd)
      72  	    && !bfd_little_endian (link_info.output_bfd)
      73  	    && !link_info.big_endian)
      74  	  {
      75  	    bfd_byte buffer[8];
      76  
      77  	    switch (statement->data_statement.type)
      78  	      {
      79  	      case QUAD:
      80  	      case SQUAD:
      81  		if (sizeof (bfd_vma) >= QUAD_SIZE)
      82  		  {
      83  		    bfd_putl64 (value, buffer);
      84  		    value = bfd_getb64 (buffer);
      85  		    break;
      86  		  }
      87  		/* Fall through.  */
      88  	      case LONG:
      89  		bfd_putl32 (value, buffer);
      90  		value = bfd_getb32 (buffer);
      91  		break;
      92  	      case SHORT:
      93  		bfd_putl16 (value, buffer);
      94  		value = bfd_getb16 (buffer);
      95  		break;
      96  	      case BYTE:
      97  		break;
      98  	      default:
      99  		abort ();
     100  	      }
     101  	  }
     102  
     103  	ASSERT (output_section->owner == link_info.output_bfd);
     104  	switch (statement->data_statement.type)
     105  	  {
     106  	  case QUAD:
     107  	  case SQUAD:
     108  	    if (sizeof (bfd_vma) >= QUAD_SIZE)
     109  	      bfd_put_64 (link_info.output_bfd, value,
     110  			  link_order->u.data.contents);
     111  	    else
     112  	      {
     113  		bfd_vma high;
     114  
     115  		if (statement->data_statement.type == QUAD)
     116  		  high = 0;
     117  		else if ((value & 0x80000000) == 0)
     118  		  high = 0;
     119  		else
     120  		  high = (bfd_vma) -1;
     121  		bfd_put_32 (link_info.output_bfd, high,
     122  			    (link_order->u.data.contents
     123  			     + (link_info.big_endian ? 0 : 4)));
     124  		bfd_put_32 (link_info.output_bfd, value,
     125  			    (link_order->u.data.contents
     126  			     + (link_info.big_endian ? 4 : 0)));
     127  	      }
     128  	    link_order->size = QUAD_SIZE;
     129  	    break;
     130  	  case LONG:
     131  	    bfd_put_32 (link_info.output_bfd, value,
     132  			link_order->u.data.contents);
     133  	    link_order->size = LONG_SIZE;
     134  	    break;
     135  	  case SHORT:
     136  	    bfd_put_16 (link_info.output_bfd, value,
     137  			link_order->u.data.contents);
     138  	    link_order->size = SHORT_SIZE;
     139  	    break;
     140  	  case BYTE:
     141  	    bfd_put_8 (link_info.output_bfd, value,
     142  		       link_order->u.data.contents);
     143  	    link_order->size = BYTE_SIZE;
     144  	    break;
     145  	  default:
     146  	    abort ();
     147  	  }
     148  	link_order->u.data.size = link_order->size;
     149        }
     150        break;
     151  
     152      case lang_reloc_statement_enum:
     153        {
     154  	lang_reloc_statement_type *rs;
     155  	asection *output_section;
     156  	struct bfd_link_order *link_order;
     157  
     158  	rs = &statement->reloc_statement;
     159  
     160  	output_section = rs->output_section;
     161  	ASSERT (output_section->owner == link_info.output_bfd);
     162  
     163  	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
     164  	      || ((output_section->flags & SEC_LOAD) != 0
     165  		  && (output_section->flags & SEC_THREAD_LOCAL))))
     166  	  break;
     167  
     168  	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
     169  	if (link_order == NULL)
     170  	  einfo (_("%F%P: bfd_new_link_order failed\n"));
     171  
     172  	link_order->offset = rs->output_offset;
     173  	link_order->size = bfd_get_reloc_size (rs->howto);
     174  
     175  	link_order->u.reloc.p = (struct bfd_link_order_reloc *)
     176  	  xmalloc (sizeof (struct bfd_link_order_reloc));
     177  
     178  	link_order->u.reloc.p->reloc = rs->reloc;
     179  	link_order->u.reloc.p->addend = rs->addend_value;
     180  
     181  	if (rs->name == NULL)
     182  	  {
     183  	    link_order->type = bfd_section_reloc_link_order;
     184  	    if (rs->section->owner == link_info.output_bfd)
     185  	      link_order->u.reloc.p->u.section = rs->section;
     186  	    else
     187  	      {
     188  		link_order->u.reloc.p->u.section = rs->section->output_section;
     189  		link_order->u.reloc.p->addend += rs->section->output_offset;
     190  	      }
     191  	  }
     192  	else
     193  	  {
     194  	    link_order->type = bfd_symbol_reloc_link_order;
     195  	    link_order->u.reloc.p->u.name = rs->name;
     196  	  }
     197        }
     198        break;
     199  
     200      case lang_input_section_enum:
     201        {
     202  	/* Create a new link_order in the output section with this
     203  	   attached */
     204  	asection *i = statement->input_section.section;
     205  
     206  	if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
     207  	    && (i->flags & SEC_EXCLUDE) == 0)
     208  	  {
     209  	    asection *output_section = i->output_section;
     210  	    struct bfd_link_order *link_order;
     211  
     212  	    ASSERT (output_section->owner == link_info.output_bfd);
     213  
     214  	    if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
     215  		  || ((output_section->flags & SEC_LOAD) != 0
     216  		      && (output_section->flags & SEC_THREAD_LOCAL))))
     217  	      break;
     218  
     219  	    link_order = bfd_new_link_order (link_info.output_bfd,
     220  					     output_section);
     221  	    if (link_order == NULL)
     222  	      einfo (_("%F%P: bfd_new_link_order failed\n"));
     223  
     224  	    if ((i->flags & SEC_NEVER_LOAD) != 0
     225  		&& (i->flags & SEC_DEBUGGING) == 0)
     226  	      {
     227  		/* We've got a never load section inside one which is
     228  		   going to be output, we'll change it into a fill.  */
     229  		link_order->type = bfd_data_link_order;
     230  		link_order->u.data.contents = (unsigned char *) "";
     231  		link_order->u.data.size = 1;
     232  	      }
     233  	    else
     234  	      {
     235  		link_order->type = bfd_indirect_link_order;
     236  		link_order->u.indirect.section = i;
     237  		ASSERT (i->output_section == output_section);
     238  	      }
     239  	    link_order->size = i->size;
     240  	    link_order->offset = i->output_offset;
     241  	  }
     242        }
     243        break;
     244  
     245      case lang_padding_statement_enum:
     246        /* Make a new link_order with the right filler */
     247        {
     248  	asection *output_section;
     249  	struct bfd_link_order *link_order;
     250  
     251  	output_section = statement->padding_statement.output_section;
     252  	ASSERT (statement->padding_statement.output_section->owner
     253  		== link_info.output_bfd);
     254  
     255  	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
     256  	      || ((output_section->flags & SEC_LOAD) != 0
     257  		  && (output_section->flags & SEC_THREAD_LOCAL))))
     258  	  break;
     259  
     260  	link_order = bfd_new_link_order (link_info.output_bfd,
     261  					 output_section);
     262  	if (link_order == NULL)
     263  	  einfo (_("%F%P: bfd_new_link_order failed\n"));
     264  	link_order->type = bfd_data_link_order;
     265  	link_order->size = statement->padding_statement.size;
     266  	link_order->offset = statement->padding_statement.output_offset;
     267  	link_order->u.data.contents = statement->padding_statement.fill->data;
     268  	link_order->u.data.size = statement->padding_statement.fill->size;
     269        }
     270        break;
     271  
     272      default:
     273        /* All the other ones fall through */
     274        break;
     275      }
     276  }
     277  
     278  /* Return true if NAME is the name of an unsplittable section. These
     279     are the stabs strings, dwarf strings.  */
     280  
     281  static bool
     282  unsplittable_name (const char *name)
     283  {
     284    if (startswith (name, ".stab"))
     285      {
     286        /* There are several stab like string sections. We pattern match on
     287  	 ".stab...str"  */
     288        unsigned len = strlen (name);
     289        if (strcmp (&name[len-3], "str") == 0)
     290  	return true;
     291      }
     292    else if (strcmp (name, "$GDB_STRINGS$") == 0)
     293      return true;
     294    return false;
     295  }
     296  
     297  /* Wander around the input sections, make sure that
     298     we'll never try and create an output section with more relocs
     299     than will fit.. Do this by always assuming the worst case, and
     300     creating new output sections with all the right bits.  */
     301  #define TESTIT 1
     302  static asection *
     303  clone_section (bfd *abfd, asection *s, const char *name, int *count)
     304  {
     305    char *tname;
     306    char *sname;
     307    unsigned int len;
     308    asection *n;
     309    struct bfd_link_hash_entry *h;
     310  
     311    /* Invent a section name from the section name and a dotted numeric
     312       suffix.   */
     313    len = strlen (name);
     314    tname = (char *) xmalloc (len + 1);
     315    memcpy (tname, name, len + 1);
     316    /* Remove a dotted number suffix, from a previous split link. */
     317    while (len && ISDIGIT (tname[len-1]))
     318      len--;
     319    if (len > 1 && tname[len-1] == '.')
     320      /* It was a dotted number. */
     321      tname[len-1] = 0;
     322  
     323    /* We want to use the whole of the original section name for the
     324       split name, but coff can be restricted to 8 character names.  */
     325    if (bfd_family_coff (abfd) && strlen (tname) > 5)
     326      {
     327        /* Some section names cannot be truncated, as the name is
     328  	 used to locate some other section.  */
     329        if (startswith (name, ".stab")
     330  	  || strcmp (name, "$GDB_SYMBOLS$") == 0)
     331  	{
     332  	  einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
     333  	  /* Silence gcc warnings.  einfo exits, so we never reach here.  */
     334  	  return NULL;
     335  	}
     336        tname[5] = 0;
     337      }
     338  
     339    if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
     340        || (n = bfd_make_section_anyway (abfd, sname)) == NULL
     341        || (h = bfd_link_hash_lookup (link_info.hash,
     342  				    sname, true, true, false)) == NULL)
     343      {
     344        einfo (_("%F%P: clone section failed: %E\n"));
     345        /* Silence gcc warnings.  einfo exits, so we never reach here.  */
     346        return NULL;
     347      }
     348    free (tname);
     349  
     350    /* Set up section symbol.  */
     351    h->type = bfd_link_hash_defined;
     352    h->u.def.value = 0;
     353    h->u.def.section = n;
     354  
     355    n->flags = s->flags;
     356    n->vma = s->vma;
     357    n->user_set_vma = s->user_set_vma;
     358    n->lma = s->lma;
     359    n->size = 0;
     360    n->output_offset = s->output_offset;
     361    n->output_section = n;
     362    n->orelocation = 0;
     363    n->reloc_count = 0;
     364    n->alignment_power = s->alignment_power;
     365  
     366    bfd_copy_private_section_data (abfd, s, abfd, n);
     367  
     368    return n;
     369  }
     370  
     371  #if TESTING
     372  static void
     373  ds (asection *s)
     374  {
     375    struct bfd_link_order *l = s->map_head.link_order;
     376    printf ("vma %x size %x\n", s->vma, s->size);
     377    while (l)
     378      {
     379        if (l->type == bfd_indirect_link_order)
     380  	printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
     381        else
     382  	printf (_("%8x something else\n"), l->offset);
     383        l = l->next;
     384      }
     385    printf ("\n");
     386  }
     387  
     388  dump (char *s, asection *a1, asection *a2)
     389  {
     390    printf ("%s\n", s);
     391    ds (a1);
     392    ds (a2);
     393  }
     394  
     395  static void
     396  sanity_check (bfd *abfd)
     397  {
     398    asection *s;
     399    for (s = abfd->sections; s; s = s->next)
     400      {
     401        struct bfd_link_order *p;
     402        bfd_vma prev = 0;
     403        for (p = s->map_head.link_order; p; p = p->next)
     404  	{
     405  	  if (p->offset > 100000)
     406  	    abort ();
     407  	  if (p->offset < prev)
     408  	    abort ();
     409  	  prev = p->offset;
     410  	}
     411      }
     412  }
     413  #else
     414  #define sanity_check(a)
     415  #define dump(a, b, c)
     416  #endif
     417  
     418  static void
     419  split_sections (bfd *abfd, struct bfd_link_info *info)
     420  {
     421    asection *original_sec;
     422    int nsecs = abfd->section_count;
     423    sanity_check (abfd);
     424    /* Look through all the original sections.  */
     425    for (original_sec = abfd->sections;
     426         original_sec && nsecs;
     427         original_sec = original_sec->next, nsecs--)
     428      {
     429        int count = 0;
     430        unsigned int lines = 0;
     431        unsigned int relocs = 0;
     432        bfd_size_type sec_size = 0;
     433        struct bfd_link_order *l;
     434        struct bfd_link_order *p;
     435        bfd_vma vma = original_sec->vma;
     436        asection *cursor = original_sec;
     437  
     438        /* Count up the relocations and line entries to see if anything
     439  	 would be too big to fit.  Accumulate section size too.  */
     440        for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next)
     441  	{
     442  	  unsigned int thislines = 0;
     443  	  unsigned int thisrelocs = 0;
     444  	  bfd_size_type thissize = 0;
     445  	  if (p->type == bfd_indirect_link_order)
     446  	    {
     447  	      asection *sec;
     448  
     449  	      sec = p->u.indirect.section;
     450  
     451  	      if (info->strip == strip_none
     452  		  || info->strip == strip_some)
     453  		thislines = sec->lineno_count;
     454  
     455  	      if (bfd_link_relocatable (info))
     456  		thisrelocs = sec->reloc_count;
     457  
     458  	      thissize = sec->size;
     459  
     460  	    }
     461  	  else if (bfd_link_relocatable (info)
     462  		   && (p->type == bfd_section_reloc_link_order
     463  		       || p->type == bfd_symbol_reloc_link_order))
     464  	    thisrelocs++;
     465  
     466  	  if (l != NULL
     467  	      && (thisrelocs + relocs >= config.split_by_reloc
     468  		  || thislines + lines >= config.split_by_reloc
     469  		  || (thissize + sec_size >= config.split_by_file))
     470  	      && !unsplittable_name (cursor->name))
     471  	    {
     472  	      /* Create a new section and put this link order and the
     473  		 following link orders into it.  */
     474  	      bfd_vma shift_offset;
     475  	      asection *n;
     476  
     477  	      n = clone_section (abfd, cursor, original_sec->name, &count);
     478  
     479  	      /* Attach the link orders to the new section and snip
     480  		 them off from the old section.  */
     481  	      n->map_head.link_order = p;
     482  	      n->map_tail.link_order = cursor->map_tail.link_order;
     483  	      cursor->map_tail.link_order = l;
     484  	      l->next = NULL;
     485  	      l = p;
     486  
     487  	      /* Change the size of the original section and
     488  		 update the vma of the new one.  */
     489  
     490  	      dump ("before snip", cursor, n);
     491  
     492  	      shift_offset = p->offset;
     493  	      n->size = cursor->size - shift_offset;
     494  	      cursor->size = shift_offset;
     495  
     496  	      vma += shift_offset;
     497  	      n->lma = n->vma = vma;
     498  
     499  	      /* Run down the chain and change the output section to
     500  		 the right one, update the offsets too.  */
     501  	      do
     502  		{
     503  		  p->offset -= shift_offset;
     504  		  if (p->type == bfd_indirect_link_order)
     505  		    {
     506  		      p->u.indirect.section->output_section = n;
     507  		      p->u.indirect.section->output_offset = p->offset;
     508  		    }
     509  		  p = p->next;
     510  		}
     511  	      while (p);
     512  
     513  	      dump ("after snip", cursor, n);
     514  	      cursor = n;
     515  	      relocs = thisrelocs;
     516  	      lines = thislines;
     517  	      sec_size = thissize;
     518  	    }
     519  	  else
     520  	    {
     521  	      l = p;
     522  	      relocs += thisrelocs;
     523  	      lines += thislines;
     524  	      sec_size += thissize;
     525  	    }
     526  	}
     527      }
     528    sanity_check (abfd);
     529  }
     530  
     531  /* Call BFD to write out the linked file.  */
     532  
     533  void
     534  ldwrite (void)
     535  {
     536    /* Reset error indicator, which can typically something like invalid
     537       format from opening up the .o files.  */
     538    bfd_set_error (bfd_error_no_error);
     539    lang_clear_os_map ();
     540    lang_for_each_statement (build_link_order);
     541  
     542    if (config.split_by_reloc != (unsigned) -1
     543        || config.split_by_file != (bfd_size_type) -1)
     544      split_sections (link_info.output_bfd, &link_info);
     545    if (!bfd_final_link (link_info.output_bfd, &link_info))
     546      {
     547        /* If there was an error recorded, print it out.  Otherwise assume
     548  	 an appropriate error message like unknown symbol was printed
     549  	 out.  */
     550  
     551        if (bfd_get_error () != bfd_error_no_error)
     552  	einfo (_("%F%P: final link failed: %E\n"));
     553        else
     554  	xexit (1);
     555      }
     556  }