133965Sjdp/* Linker command language support.
278828Sobrien   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3218822Sdim   2001, 2002, 2003, 2004, 2005, 2006, 2007
438889Sjdp   Free Software Foundation, Inc.
533965Sjdp
6130561Sobrien   This file is part of GLD, the Gnu Linker.
733965Sjdp
8130561Sobrien   GLD is free software; you can redistribute it and/or modify
9130561Sobrien   it under the terms of the GNU General Public License as published by
10130561Sobrien   the Free Software Foundation; either version 2, or (at your option)
11130561Sobrien   any later version.
1233965Sjdp
13130561Sobrien   GLD is distributed in the hope that it will be useful,
14130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130561Sobrien   GNU General Public License for more details.
1733965Sjdp
18130561Sobrien   You should have received a copy of the GNU General Public License
19130561Sobrien   along with GLD; see the file COPYING.  If not, write to the Free
20218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, USA.  */
2233965Sjdp
23218822Sdim#include "sysdep.h"
2433965Sjdp#include "bfd.h"
2533965Sjdp#include "libiberty.h"
2689857Sobrien#include "safe-ctype.h"
2733965Sjdp#include "obstack.h"
2833965Sjdp#include "bfdlink.h"
2933965Sjdp
3033965Sjdp#include "ld.h"
3133965Sjdp#include "ldmain.h"
3233965Sjdp#include "ldexp.h"
3333965Sjdp#include "ldlang.h"
34107492Sobrien#include <ldgram.h>
3533965Sjdp#include "ldlex.h"
3633965Sjdp#include "ldmisc.h"
3733965Sjdp#include "ldctor.h"
3833965Sjdp#include "ldfile.h"
3977298Sobrien#include "ldemul.h"
4033965Sjdp#include "fnmatch.h"
4160484Sobrien#include "demangle.h"
42130561Sobrien#include "hashtab.h"
4333965Sjdp
44130561Sobrien#ifndef offsetof
45130561Sobrien#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER))
46130561Sobrien#endif
4733965Sjdp
48130561Sobrien/* Locals variables.  */
4933965Sjdpstatic struct obstack stat_obstack;
50218822Sdimstatic struct obstack map_obstack;
5133965Sjdp
5233965Sjdp#define obstack_chunk_alloc xmalloc
5333965Sjdp#define obstack_chunk_free free
5477298Sobrienstatic const char *startup_file;
55130561Sobrienstatic bfd_boolean placed_commons = FALSE;
56218822Sdimstatic bfd_boolean stripped_excluded_sections = FALSE;
5733965Sjdpstatic lang_output_section_statement_type *default_common_section;
58130561Sobrienstatic bfd_boolean map_option_f;
5933965Sjdpstatic bfd_vma print_dot;
6033965Sjdpstatic lang_input_statement_type *first_file;
6177298Sobrienstatic const char *current_target;
6277298Sobrienstatic const char *output_target;
6333965Sjdpstatic lang_statement_list_type statement_list;
64130561Sobrienstatic struct bfd_hash_table lang_definedness_table;
6533965Sjdp
66130561Sobrien/* Forward declarations.  */
67130561Sobrienstatic void exp_init_os (etree_type *);
68218822Sdimstatic void init_map_userdata (bfd *, asection *, void *);
69130561Sobrienstatic lang_input_statement_type *lookup_name (const char *);
70130561Sobrienstatic struct bfd_hash_entry *lang_definedness_newfunc
71130561Sobrien (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
72130561Sobrienstatic void insert_undefined (const char *);
73218822Sdimstatic bfd_boolean sort_def_symbol (struct bfd_link_hash_entry *, void *);
74130561Sobrienstatic void print_statement (lang_statement_union_type *,
75130561Sobrien			     lang_output_section_statement_type *);
76130561Sobrienstatic void print_statement_list (lang_statement_union_type *,
77130561Sobrien				  lang_output_section_statement_type *);
78130561Sobrienstatic void print_statements (void);
79218822Sdimstatic void print_input_section (asection *);
80130561Sobrienstatic bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
81130561Sobrienstatic void lang_record_phdrs (void);
82130561Sobrienstatic void lang_do_version_exports_section (void);
83218822Sdimstatic void lang_finalize_version_expr_head
84218822Sdim  (struct bfd_elf_version_expr_head *);
8533965Sjdp
86130561Sobrien/* Exported variables.  */
8733965Sjdplang_output_section_statement_type *abs_output_section;
8868765Sobrienlang_statement_list_type lang_output_section_statement;
8933965Sjdplang_statement_list_type *stat_ptr = &statement_list;
9060484Sobrienlang_statement_list_type file_chain = { NULL, NULL };
91218822Sdimlang_statement_list_type input_file_chain;
92104834Sobrienstruct bfd_sym_chain entry_symbol = { NULL, NULL };
93218822Sdimstatic const char *entry_symbol_default = "start";
9491041Sobrienconst char *entry_section = ".text";
95130561Sobrienbfd_boolean entry_from_cmdline;
96130561Sobrienbfd_boolean lang_has_input_file = FALSE;
97130561Sobrienbfd_boolean had_output_filename = FALSE;
98130561Sobrienbfd_boolean lang_float_flag = FALSE;
99130561Sobrienbfd_boolean delete_output_file_on_failure = FALSE;
100218822Sdimstruct lang_phdr *lang_phdr_list;
10133965Sjdpstruct lang_nocrossrefs *nocrossref_list;
102218822Sdimstatic struct unique_sections *unique_section_list;
103130561Sobrienstatic bfd_boolean ldlang_sysrooted_script = FALSE;
104218822Sdim
105218822Sdim /* Functions that traverse the linker script and might evaluate
106218822Sdim    DEFINED() need to increment this.  */
107130561Sobrienint lang_statement_iteration = 0;
10833965Sjdp
10933965Sjdpetree_type *base; /* Relocation base - or null */
11033965Sjdp
111218822Sdim/* Return TRUE if the PATTERN argument is a wildcard pattern.
112218822Sdim   Although backslashes are treated specially if a pattern contains
113218822Sdim   wildcards, we do not consider the mere presence of a backslash to
114218822Sdim   be enough to cause the pattern to be treated as a wildcard.
115218822Sdim   That lets us handle DOS filenames more naturally.  */
116218822Sdim#define wildcardp(pattern) (strpbrk ((pattern), "?*[") != NULL)
117218822Sdim
11878828Sobrien#define new_stat(x, y) \
119130561Sobrien  (x##_type *) new_statement (x##_enum, sizeof (x##_type), y)
12033965Sjdp
12178828Sobrien#define outside_section_address(q) \
12278828Sobrien  ((q)->output_offset + (q)->output_section->vma)
12333965Sjdp
12478828Sobrien#define outside_symbol_address(q) \
12578828Sobrien  ((q)->value + outside_section_address (q->section))
12633965Sjdp
12733965Sjdp#define SECTION_NAME_MAP_LENGTH (16)
12833965Sjdp
129130561Sobrienvoid *
130130561Sobrienstat_alloc (size_t size)
13133965Sjdp{
13233965Sjdp  return obstack_alloc (&stat_obstack, size);
13333965Sjdp}
13433965Sjdp
135130561Sobrienbfd_boolean
136218822Sdimunique_section_p (const asection *sec)
13777298Sobrien{
13877298Sobrien  struct unique_sections *unam;
139218822Sdim  const char *secnam;
14060484Sobrien
141218822Sdim  if (link_info.relocatable
142218822Sdim      && sec->owner != NULL
143218822Sdim      && bfd_is_group_section (sec->owner, sec))
144218822Sdim    return TRUE;
145218822Sdim
146218822Sdim  secnam = sec->name;
14777298Sobrien  for (unam = unique_section_list; unam; unam = unam->next)
14877298Sobrien    if (wildcardp (unam->name)
14977298Sobrien	? fnmatch (unam->name, secnam, 0) == 0
15077298Sobrien	: strcmp (unam->name, secnam) == 0)
15177298Sobrien      {
152130561Sobrien	return TRUE;
15377298Sobrien      }
15477298Sobrien
155130561Sobrien  return FALSE;
15677298Sobrien}
15777298Sobrien
15877298Sobrien/* Generic traversal routines for finding matching sections.  */
15977298Sobrien
160218822Sdim/* Try processing a section against a wildcard.  This just calls
161218822Sdim   the callback unless the filename exclusion list is present
162218822Sdim   and excludes the file.  It's hardly ever present so this
163218822Sdim   function is very fast.  */
164218822Sdim
16560484Sobrienstatic void
166218822Sdimwalk_wild_consider_section (lang_wild_statement_type *ptr,
167218822Sdim			    lang_input_statement_type *file,
168218822Sdim			    asection *s,
169218822Sdim			    struct wildcard_list *sec,
170218822Sdim			    callback_t callback,
171218822Sdim			    void *data)
17260484Sobrien{
173218822Sdim  bfd_boolean skip = FALSE;
174218822Sdim  struct name_list *list_tmp;
175218822Sdim
176218822Sdim  /* Don't process sections from files which were
177218822Sdim     excluded.  */
178218822Sdim  for (list_tmp = sec->spec.exclude_name_list;
179218822Sdim       list_tmp;
180218822Sdim       list_tmp = list_tmp->next)
181218822Sdim    {
182218822Sdim      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
183218822Sdim      if (is_wildcard)
184218822Sdim	skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
185218822Sdim      else
186218822Sdim	skip = strcmp (list_tmp->name, file->filename) == 0;
187218822Sdim
188218822Sdim      /* If this file is part of an archive, and the archive is
189218822Sdim	 excluded, exclude this file.  */
190218822Sdim      if (! skip && file->the_bfd != NULL
191218822Sdim	  && file->the_bfd->my_archive != NULL
192218822Sdim	  && file->the_bfd->my_archive->filename != NULL)
193218822Sdim	{
194218822Sdim	  if (is_wildcard)
195218822Sdim	    skip = fnmatch (list_tmp->name,
196218822Sdim			    file->the_bfd->my_archive->filename,
197218822Sdim			    0) == 0;
198218822Sdim	  else
199218822Sdim	    skip = strcmp (list_tmp->name,
200218822Sdim			   file->the_bfd->my_archive->filename) == 0;
201218822Sdim	}
202218822Sdim
203218822Sdim      if (skip)
204218822Sdim	break;
205218822Sdim    }
206218822Sdim
207218822Sdim  if (!skip)
208218822Sdim    (*callback) (ptr, sec, s, file, data);
209218822Sdim}
210218822Sdim
211218822Sdim/* Lowest common denominator routine that can handle everything correctly,
212218822Sdim   but slowly.  */
213218822Sdim
214218822Sdimstatic void
215218822Sdimwalk_wild_section_general (lang_wild_statement_type *ptr,
216218822Sdim			   lang_input_statement_type *file,
217218822Sdim			   callback_t callback,
218218822Sdim			   void *data)
219218822Sdim{
22089857Sobrien  asection *s;
221218822Sdim  struct wildcard_list *sec;
22289857Sobrien
22389857Sobrien  for (s = file->the_bfd->sections; s != NULL; s = s->next)
22460484Sobrien    {
22589857Sobrien      sec = ptr->section_list;
22689857Sobrien      if (sec == NULL)
22789857Sobrien	(*callback) (ptr, sec, s, file, data);
22889857Sobrien
22989857Sobrien      while (sec != NULL)
23077298Sobrien	{
231130561Sobrien	  bfd_boolean skip = FALSE;
23260484Sobrien
233218822Sdim	  if (sec->spec.name != NULL)
23489857Sobrien	    {
23589857Sobrien	      const char *sname = bfd_get_section_name (file->the_bfd, s);
23660484Sobrien
23789857Sobrien	      if (wildcardp (sec->spec.name))
23889857Sobrien		skip = fnmatch (sec->spec.name, sname, 0) != 0;
23989857Sobrien	      else
24089857Sobrien		skip = strcmp (sec->spec.name, sname) != 0;
24189857Sobrien	    }
24260484Sobrien
24389857Sobrien	  if (!skip)
244218822Sdim	    walk_wild_consider_section (ptr, file, s, sec, callback, data);
24560484Sobrien
24689857Sobrien	  sec = sec->next;
24760484Sobrien	}
24860484Sobrien    }
24960484Sobrien}
25060484Sobrien
251218822Sdim/* Routines to find a single section given its name.  If there's more
252218822Sdim   than one section with that name, we report that.  */
253218822Sdim
254218822Sdimtypedef struct
255218822Sdim{
256218822Sdim  asection *found_section;
257218822Sdim  bfd_boolean multiple_sections_found;
258218822Sdim} section_iterator_callback_data;
259218822Sdim
260218822Sdimstatic bfd_boolean
261218822Sdimsection_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
262218822Sdim{
263218822Sdim  section_iterator_callback_data *d = data;
264218822Sdim
265218822Sdim  if (d->found_section != NULL)
266218822Sdim    {
267218822Sdim      d->multiple_sections_found = TRUE;
268218822Sdim      return TRUE;
269218822Sdim    }
270218822Sdim
271218822Sdim  d->found_section = s;
272218822Sdim  return FALSE;
273218822Sdim}
274218822Sdim
275218822Sdimstatic asection *
276218822Sdimfind_section (lang_input_statement_type *file,
277218822Sdim	      struct wildcard_list *sec,
278218822Sdim	      bfd_boolean *multiple_sections_found)
279218822Sdim{
280218822Sdim  section_iterator_callback_data cb_data = { NULL, FALSE };
281218822Sdim
282218822Sdim  bfd_get_section_by_name_if (file->the_bfd, sec->spec.name,
283218822Sdim			      section_iterator_callback, &cb_data);
284218822Sdim  *multiple_sections_found = cb_data.multiple_sections_found;
285218822Sdim  return cb_data.found_section;
286218822Sdim}
287218822Sdim
288218822Sdim/* Code for handling simple wildcards without going through fnmatch,
289218822Sdim   which can be expensive because of charset translations etc.  */
290218822Sdim
291218822Sdim/* A simple wild is a literal string followed by a single '*',
292218822Sdim   where the literal part is at least 4 characters long.  */
293218822Sdim
294218822Sdimstatic bfd_boolean
295218822Sdimis_simple_wild (const char *name)
296218822Sdim{
297218822Sdim  size_t len = strcspn (name, "*?[");
298218822Sdim  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
299218822Sdim}
300218822Sdim
301218822Sdimstatic bfd_boolean
302218822Sdimmatch_simple_wild (const char *pattern, const char *name)
303218822Sdim{
304218822Sdim  /* The first four characters of the pattern are guaranteed valid
305218822Sdim     non-wildcard characters.  So we can go faster.  */
306218822Sdim  if (pattern[0] != name[0] || pattern[1] != name[1]
307218822Sdim      || pattern[2] != name[2] || pattern[3] != name[3])
308218822Sdim    return FALSE;
309218822Sdim
310218822Sdim  pattern += 4;
311218822Sdim  name += 4;
312218822Sdim  while (*pattern != '*')
313218822Sdim    if (*name++ != *pattern++)
314218822Sdim      return FALSE;
315218822Sdim
316218822Sdim  return TRUE;
317218822Sdim}
318218822Sdim
319218822Sdim/* Compare sections ASEC and BSEC according to SORT.  */
320218822Sdim
321218822Sdimstatic int
322218822Sdimcompare_section (sort_type sort, asection *asec, asection *bsec)
323218822Sdim{
324218822Sdim  int ret;
325218822Sdim
326218822Sdim  switch (sort)
327218822Sdim    {
328218822Sdim    default:
329218822Sdim      abort ();
330218822Sdim
331218822Sdim    case by_alignment_name:
332218822Sdim      ret = (bfd_section_alignment (bsec->owner, bsec)
333218822Sdim	     - bfd_section_alignment (asec->owner, asec));
334218822Sdim      if (ret)
335218822Sdim	break;
336218822Sdim      /* Fall through.  */
337218822Sdim
338218822Sdim    case by_name:
339218822Sdim      ret = strcmp (bfd_get_section_name (asec->owner, asec),
340218822Sdim		    bfd_get_section_name (bsec->owner, bsec));
341218822Sdim      break;
342218822Sdim
343218822Sdim    case by_name_alignment:
344218822Sdim      ret = strcmp (bfd_get_section_name (asec->owner, asec),
345218822Sdim		    bfd_get_section_name (bsec->owner, bsec));
346218822Sdim      if (ret)
347218822Sdim	break;
348218822Sdim      /* Fall through.  */
349218822Sdim
350218822Sdim    case by_alignment:
351218822Sdim      ret = (bfd_section_alignment (bsec->owner, bsec)
352218822Sdim	     - bfd_section_alignment (asec->owner, asec));
353218822Sdim      break;
354218822Sdim    }
355218822Sdim
356218822Sdim  return ret;
357218822Sdim}
358218822Sdim
359218822Sdim/* Build a Binary Search Tree to sort sections, unlike insertion sort
360218822Sdim   used in wild_sort(). BST is considerably faster if the number of
361218822Sdim   of sections are large.  */
362218822Sdim
363218822Sdimstatic lang_section_bst_type **
364218822Sdimwild_sort_fast (lang_wild_statement_type *wild,
365218822Sdim		struct wildcard_list *sec,
366218822Sdim		lang_input_statement_type *file ATTRIBUTE_UNUSED,
367218822Sdim		asection *section)
368218822Sdim{
369218822Sdim  lang_section_bst_type **tree;
370218822Sdim
371218822Sdim  tree = &wild->tree;
372218822Sdim  if (!wild->filenames_sorted
373218822Sdim      && (sec == NULL || sec->spec.sorted == none))
374218822Sdim    {
375218822Sdim      /* Append at the right end of tree.  */
376218822Sdim      while (*tree)
377218822Sdim	tree = &((*tree)->right);
378218822Sdim      return tree;
379218822Sdim    }
380218822Sdim
381218822Sdim  while (*tree)
382218822Sdim    {
383218822Sdim      /* Find the correct node to append this section.  */
384218822Sdim      if (compare_section (sec->spec.sorted, section, (*tree)->section) < 0)
385218822Sdim	tree = &((*tree)->left);
386218822Sdim      else
387218822Sdim	tree = &((*tree)->right);
388218822Sdim    }
389218822Sdim
390218822Sdim  return tree;
391218822Sdim}
392218822Sdim
393218822Sdim/* Use wild_sort_fast to build a BST to sort sections.  */
394218822Sdim
395218822Sdimstatic void
396218822Sdimoutput_section_callback_fast (lang_wild_statement_type *ptr,
397218822Sdim			      struct wildcard_list *sec,
398218822Sdim			      asection *section,
399218822Sdim			      lang_input_statement_type *file,
400218822Sdim			      void *output ATTRIBUTE_UNUSED)
401218822Sdim{
402218822Sdim  lang_section_bst_type *node;
403218822Sdim  lang_section_bst_type **tree;
404218822Sdim
405218822Sdim  if (unique_section_p (section))
406218822Sdim    return;
407218822Sdim
408218822Sdim  node = xmalloc (sizeof (lang_section_bst_type));
409218822Sdim  node->left = 0;
410218822Sdim  node->right = 0;
411218822Sdim  node->section = section;
412218822Sdim
413218822Sdim  tree = wild_sort_fast (ptr, sec, file, section);
414218822Sdim  if (tree != NULL)
415218822Sdim    *tree = node;
416218822Sdim}
417218822Sdim
418218822Sdim/* Convert a sorted sections' BST back to list form.  */
419218822Sdim
420218822Sdimstatic void
421218822Sdimoutput_section_callback_tree_to_list (lang_wild_statement_type *ptr,
422218822Sdim				      lang_section_bst_type *tree,
423218822Sdim				      void *output)
424218822Sdim{
425218822Sdim  if (tree->left)
426218822Sdim    output_section_callback_tree_to_list (ptr, tree->left, output);
427218822Sdim
428218822Sdim  lang_add_section (&ptr->children, tree->section,
429218822Sdim		    (lang_output_section_statement_type *) output);
430218822Sdim
431218822Sdim  if (tree->right)
432218822Sdim    output_section_callback_tree_to_list (ptr, tree->right, output);
433218822Sdim
434218822Sdim  free (tree);
435218822Sdim}
436218822Sdim
437218822Sdim/* Specialized, optimized routines for handling different kinds of
438218822Sdim   wildcards */
439218822Sdim
440218822Sdimstatic void
441218822Sdimwalk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
442218822Sdim				lang_input_statement_type *file,
443218822Sdim				callback_t callback,
444218822Sdim				void *data)
445218822Sdim{
446218822Sdim  /* We can just do a hash lookup for the section with the right name.
447218822Sdim     But if that lookup discovers more than one section with the name
448218822Sdim     (should be rare), we fall back to the general algorithm because
449218822Sdim     we would otherwise have to sort the sections to make sure they
450218822Sdim     get processed in the bfd's order.  */
451218822Sdim  bfd_boolean multiple_sections_found;
452218822Sdim  struct wildcard_list *sec0 = ptr->handler_data[0];
453218822Sdim  asection *s0 = find_section (file, sec0, &multiple_sections_found);
454218822Sdim
455218822Sdim  if (multiple_sections_found)
456218822Sdim    walk_wild_section_general (ptr, file, callback, data);
457218822Sdim  else if (s0)
458218822Sdim    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
459218822Sdim}
460218822Sdim
461218822Sdimstatic void
462218822Sdimwalk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
463218822Sdim				lang_input_statement_type *file,
464218822Sdim				callback_t callback,
465218822Sdim				void *data)
466218822Sdim{
467218822Sdim  asection *s;
468218822Sdim  struct wildcard_list *wildsec0 = ptr->handler_data[0];
469218822Sdim
470218822Sdim  for (s = file->the_bfd->sections; s != NULL; s = s->next)
471218822Sdim    {
472218822Sdim      const char *sname = bfd_get_section_name (file->the_bfd, s);
473218822Sdim      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
474218822Sdim
475218822Sdim      if (!skip)
476218822Sdim	walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
477218822Sdim    }
478218822Sdim}
479218822Sdim
480218822Sdimstatic void
481218822Sdimwalk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
482218822Sdim				lang_input_statement_type *file,
483218822Sdim				callback_t callback,
484218822Sdim				void *data)
485218822Sdim{
486218822Sdim  asection *s;
487218822Sdim  struct wildcard_list *sec0 = ptr->handler_data[0];
488218822Sdim  struct wildcard_list *wildsec1 = ptr->handler_data[1];
489218822Sdim  bfd_boolean multiple_sections_found;
490218822Sdim  asection *s0 = find_section (file, sec0, &multiple_sections_found);
491218822Sdim
492218822Sdim  if (multiple_sections_found)
493218822Sdim    {
494218822Sdim      walk_wild_section_general (ptr, file, callback, data);
495218822Sdim      return;
496218822Sdim    }
497218822Sdim
498218822Sdim  /* Note that if the section was not found, s0 is NULL and
499218822Sdim     we'll simply never succeed the s == s0 test below.  */
500218822Sdim  for (s = file->the_bfd->sections; s != NULL; s = s->next)
501218822Sdim    {
502218822Sdim      /* Recall that in this code path, a section cannot satisfy more
503218822Sdim	 than one spec, so if s == s0 then it cannot match
504218822Sdim	 wildspec1.  */
505218822Sdim      if (s == s0)
506218822Sdim	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
507218822Sdim      else
508218822Sdim	{
509218822Sdim	  const char *sname = bfd_get_section_name (file->the_bfd, s);
510218822Sdim	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
511218822Sdim
512218822Sdim	  if (!skip)
513218822Sdim	    walk_wild_consider_section (ptr, file, s, wildsec1, callback,
514218822Sdim					data);
515218822Sdim	}
516218822Sdim    }
517218822Sdim}
518218822Sdim
519218822Sdimstatic void
520218822Sdimwalk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
521218822Sdim				lang_input_statement_type *file,
522218822Sdim				callback_t callback,
523218822Sdim				void *data)
524218822Sdim{
525218822Sdim  asection *s;
526218822Sdim  struct wildcard_list *sec0 = ptr->handler_data[0];
527218822Sdim  struct wildcard_list *wildsec1 = ptr->handler_data[1];
528218822Sdim  struct wildcard_list *wildsec2 = ptr->handler_data[2];
529218822Sdim  bfd_boolean multiple_sections_found;
530218822Sdim  asection *s0 = find_section (file, sec0, &multiple_sections_found);
531218822Sdim
532218822Sdim  if (multiple_sections_found)
533218822Sdim    {
534218822Sdim      walk_wild_section_general (ptr, file, callback, data);
535218822Sdim      return;
536218822Sdim    }
537218822Sdim
538218822Sdim  for (s = file->the_bfd->sections; s != NULL; s = s->next)
539218822Sdim    {
540218822Sdim      if (s == s0)
541218822Sdim	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
542218822Sdim      else
543218822Sdim	{
544218822Sdim	  const char *sname = bfd_get_section_name (file->the_bfd, s);
545218822Sdim	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
546218822Sdim
547218822Sdim	  if (!skip)
548218822Sdim	    walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
549218822Sdim	  else
550218822Sdim	    {
551218822Sdim	      skip = !match_simple_wild (wildsec2->spec.name, sname);
552218822Sdim	      if (!skip)
553218822Sdim		walk_wild_consider_section (ptr, file, s, wildsec2, callback,
554218822Sdim					    data);
555218822Sdim	    }
556218822Sdim	}
557218822Sdim    }
558218822Sdim}
559218822Sdim
560218822Sdimstatic void
561218822Sdimwalk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
562218822Sdim				lang_input_statement_type *file,
563218822Sdim				callback_t callback,
564218822Sdim				void *data)
565218822Sdim{
566218822Sdim  asection *s;
567218822Sdim  struct wildcard_list *sec0 = ptr->handler_data[0];
568218822Sdim  struct wildcard_list *sec1 = ptr->handler_data[1];
569218822Sdim  struct wildcard_list *wildsec2 = ptr->handler_data[2];
570218822Sdim  struct wildcard_list *wildsec3 = ptr->handler_data[3];
571218822Sdim  bfd_boolean multiple_sections_found;
572218822Sdim  asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
573218822Sdim
574218822Sdim  if (multiple_sections_found)
575218822Sdim    {
576218822Sdim      walk_wild_section_general (ptr, file, callback, data);
577218822Sdim      return;
578218822Sdim    }
579218822Sdim
580218822Sdim  s1 = find_section (file, sec1, &multiple_sections_found);
581218822Sdim  if (multiple_sections_found)
582218822Sdim    {
583218822Sdim      walk_wild_section_general (ptr, file, callback, data);
584218822Sdim      return;
585218822Sdim    }
586218822Sdim
587218822Sdim  for (s = file->the_bfd->sections; s != NULL; s = s->next)
588218822Sdim    {
589218822Sdim      if (s == s0)
590218822Sdim	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
591218822Sdim      else
592218822Sdim	if (s == s1)
593218822Sdim	  walk_wild_consider_section (ptr, file, s, sec1, callback, data);
594218822Sdim	else
595218822Sdim	  {
596218822Sdim	    const char *sname = bfd_get_section_name (file->the_bfd, s);
597218822Sdim	    bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
598218822Sdim						   sname);
599218822Sdim
600218822Sdim	    if (!skip)
601218822Sdim	      walk_wild_consider_section (ptr, file, s, wildsec2, callback,
602218822Sdim					  data);
603218822Sdim	    else
604218822Sdim	      {
605218822Sdim		skip = !match_simple_wild (wildsec3->spec.name, sname);
606218822Sdim		if (!skip)
607218822Sdim		  walk_wild_consider_section (ptr, file, s, wildsec3,
608218822Sdim					      callback, data);
609218822Sdim	      }
610218822Sdim	  }
611218822Sdim    }
612218822Sdim}
613218822Sdim
614218822Sdimstatic void
615218822Sdimwalk_wild_section (lang_wild_statement_type *ptr,
616218822Sdim		   lang_input_statement_type *file,
617218822Sdim		   callback_t callback,
618218822Sdim		   void *data)
619218822Sdim{
620218822Sdim  if (file->just_syms_flag)
621218822Sdim    return;
622218822Sdim
623218822Sdim  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
624218822Sdim}
625218822Sdim
626218822Sdim/* Returns TRUE when name1 is a wildcard spec that might match
627218822Sdim   something name2 can match.  We're conservative: we return FALSE
628218822Sdim   only if the prefixes of name1 and name2 are different up to the
629218822Sdim   first wildcard character.  */
630218822Sdim
631218822Sdimstatic bfd_boolean
632218822Sdimwild_spec_can_overlap (const char *name1, const char *name2)
633218822Sdim{
634218822Sdim  size_t prefix1_len = strcspn (name1, "?*[");
635218822Sdim  size_t prefix2_len = strcspn (name2, "?*[");
636218822Sdim  size_t min_prefix_len;
637218822Sdim
638218822Sdim  /* Note that if there is no wildcard character, then we treat the
639218822Sdim     terminating 0 as part of the prefix.  Thus ".text" won't match
640218822Sdim     ".text." or ".text.*", for example.  */
641218822Sdim  if (name1[prefix1_len] == '\0')
642218822Sdim    prefix1_len++;
643218822Sdim  if (name2[prefix2_len] == '\0')
644218822Sdim    prefix2_len++;
645218822Sdim
646218822Sdim  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
647218822Sdim
648218822Sdim  return memcmp (name1, name2, min_prefix_len) == 0;
649218822Sdim}
650218822Sdim
651218822Sdim/* Select specialized code to handle various kinds of wildcard
652218822Sdim   statements.  */
653218822Sdim
654218822Sdimstatic void
655218822Sdimanalyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
656218822Sdim{
657218822Sdim  int sec_count = 0;
658218822Sdim  int wild_name_count = 0;
659218822Sdim  struct wildcard_list *sec;
660218822Sdim  int signature;
661218822Sdim  int data_counter;
662218822Sdim
663218822Sdim  ptr->walk_wild_section_handler = walk_wild_section_general;
664218822Sdim  ptr->handler_data[0] = NULL;
665218822Sdim  ptr->handler_data[1] = NULL;
666218822Sdim  ptr->handler_data[2] = NULL;
667218822Sdim  ptr->handler_data[3] = NULL;
668218822Sdim  ptr->tree = NULL;
669218822Sdim
670218822Sdim  /* Count how many wildcard_specs there are, and how many of those
671218822Sdim     actually use wildcards in the name.  Also, bail out if any of the
672218822Sdim     wildcard names are NULL. (Can this actually happen?
673218822Sdim     walk_wild_section used to test for it.)  And bail out if any
674218822Sdim     of the wildcards are more complex than a simple string
675218822Sdim     ending in a single '*'.  */
676218822Sdim  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
677218822Sdim    {
678218822Sdim      ++sec_count;
679218822Sdim      if (sec->spec.name == NULL)
680218822Sdim	return;
681218822Sdim      if (wildcardp (sec->spec.name))
682218822Sdim	{
683218822Sdim	  ++wild_name_count;
684218822Sdim	  if (!is_simple_wild (sec->spec.name))
685218822Sdim	    return;
686218822Sdim	}
687218822Sdim    }
688218822Sdim
689218822Sdim  /* The zero-spec case would be easy to optimize but it doesn't
690218822Sdim     happen in practice.  Likewise, more than 4 specs doesn't
691218822Sdim     happen in practice.  */
692218822Sdim  if (sec_count == 0 || sec_count > 4)
693218822Sdim    return;
694218822Sdim
695218822Sdim  /* Check that no two specs can match the same section.  */
696218822Sdim  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
697218822Sdim    {
698218822Sdim      struct wildcard_list *sec2;
699218822Sdim      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
700218822Sdim	{
701218822Sdim	  if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
702218822Sdim	    return;
703218822Sdim	}
704218822Sdim    }
705218822Sdim
706218822Sdim  signature = (sec_count << 8) + wild_name_count;
707218822Sdim  switch (signature)
708218822Sdim    {
709218822Sdim    case 0x0100:
710218822Sdim      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
711218822Sdim      break;
712218822Sdim    case 0x0101:
713218822Sdim      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
714218822Sdim      break;
715218822Sdim    case 0x0201:
716218822Sdim      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
717218822Sdim      break;
718218822Sdim    case 0x0302:
719218822Sdim      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
720218822Sdim      break;
721218822Sdim    case 0x0402:
722218822Sdim      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
723218822Sdim      break;
724218822Sdim    default:
725218822Sdim      return;
726218822Sdim    }
727218822Sdim
728218822Sdim  /* Now fill the data array with pointers to the specs, first the
729218822Sdim     specs with non-wildcard names, then the specs with wildcard
730218822Sdim     names.  It's OK to process the specs in different order from the
731218822Sdim     given order, because we've already determined that no section
732218822Sdim     will match more than one spec.  */
733218822Sdim  data_counter = 0;
734218822Sdim  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
735218822Sdim    if (!wildcardp (sec->spec.name))
736218822Sdim      ptr->handler_data[data_counter++] = sec;
737218822Sdim  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
738218822Sdim    if (wildcardp (sec->spec.name))
739218822Sdim      ptr->handler_data[data_counter++] = sec;
740218822Sdim}
741218822Sdim
74260484Sobrien/* Handle a wild statement for a single file F.  */
74360484Sobrien
74460484Sobrienstatic void
745130561Sobrienwalk_wild_file (lang_wild_statement_type *s,
746130561Sobrien		lang_input_statement_type *f,
747130561Sobrien		callback_t callback,
748130561Sobrien		void *data)
74960484Sobrien{
75060484Sobrien  if (f->the_bfd == NULL
75160484Sobrien      || ! bfd_check_format (f->the_bfd, bfd_archive))
75289857Sobrien    walk_wild_section (s, f, callback, data);
75360484Sobrien  else
75460484Sobrien    {
75560484Sobrien      bfd *member;
75660484Sobrien
75760484Sobrien      /* This is an archive file.  We must map each member of the
75860484Sobrien	 archive separately.  */
759130561Sobrien      member = bfd_openr_next_archived_file (f->the_bfd, NULL);
76060484Sobrien      while (member != NULL)
76160484Sobrien	{
76260484Sobrien	  /* When lookup_name is called, it will call the add_symbols
76360484Sobrien	     entry point for the archive.  For each element of the
76460484Sobrien	     archive which is included, BFD will call ldlang_add_file,
76560484Sobrien	     which will set the usrdata field of the member to the
76660484Sobrien	     lang_input_statement.  */
76760484Sobrien	  if (member->usrdata != NULL)
76860484Sobrien	    {
769130561Sobrien	      walk_wild_section (s, member->usrdata, callback, data);
77060484Sobrien	    }
77160484Sobrien
77260484Sobrien	  member = bfd_openr_next_archived_file (f->the_bfd, member);
77360484Sobrien	}
77460484Sobrien    }
77560484Sobrien}
77660484Sobrien
77760484Sobrienstatic void
778130561Sobrienwalk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
77960484Sobrien{
78089857Sobrien  const char *file_spec = s->filename;
78189857Sobrien
78289857Sobrien  if (file_spec == NULL)
78360484Sobrien    {
78460484Sobrien      /* Perform the iteration over all files in the list.  */
78560484Sobrien      LANG_FOR_EACH_INPUT_STATEMENT (f)
78660484Sobrien	{
78789857Sobrien	  walk_wild_file (s, f, callback, data);
78860484Sobrien	}
78960484Sobrien    }
79089857Sobrien  else if (wildcardp (file_spec))
79160484Sobrien    {
79260484Sobrien      LANG_FOR_EACH_INPUT_STATEMENT (f)
79360484Sobrien	{
794218822Sdim	  if (fnmatch (file_spec, f->filename, 0) == 0)
79589857Sobrien	    walk_wild_file (s, f, callback, data);
79660484Sobrien	}
79760484Sobrien    }
79860484Sobrien  else
79960484Sobrien    {
80060484Sobrien      lang_input_statement_type *f;
80160484Sobrien
80260484Sobrien      /* Perform the iteration over a single file.  */
80389857Sobrien      f = lookup_name (file_spec);
80489857Sobrien      if (f)
80589857Sobrien	walk_wild_file (s, f, callback, data);
80660484Sobrien    }
80777298Sobrien}
80833965Sjdp
80977298Sobrien/* lang_for_each_statement walks the parse tree and calls the provided
81077298Sobrien   function for each node.  */
81177298Sobrien
81233965Sjdpstatic void
813130561Sobrienlang_for_each_statement_worker (void (*func) (lang_statement_union_type *),
814130561Sobrien				lang_statement_union_type *s)
81533965Sjdp{
816130561Sobrien  for (; s != NULL; s = s->header.next)
81733965Sjdp    {
81833965Sjdp      func (s);
81933965Sjdp
82033965Sjdp      switch (s->header.type)
82133965Sjdp	{
82233965Sjdp	case lang_constructors_statement_enum:
82333965Sjdp	  lang_for_each_statement_worker (func, constructor_list.head);
82433965Sjdp	  break;
82533965Sjdp	case lang_output_section_statement_enum:
82633965Sjdp	  lang_for_each_statement_worker
827218822Sdim	    (func, s->output_section_statement.children.head);
82833965Sjdp	  break;
82933965Sjdp	case lang_wild_statement_enum:
830218822Sdim	  lang_for_each_statement_worker (func,
831218822Sdim					  s->wild_statement.children.head);
83233965Sjdp	  break;
83333965Sjdp	case lang_group_statement_enum:
83433965Sjdp	  lang_for_each_statement_worker (func,
83533965Sjdp					  s->group_statement.children.head);
83633965Sjdp	  break;
83733965Sjdp	case lang_data_statement_enum:
83833965Sjdp	case lang_reloc_statement_enum:
83933965Sjdp	case lang_object_symbols_statement_enum:
84033965Sjdp	case lang_output_statement_enum:
84133965Sjdp	case lang_target_statement_enum:
84233965Sjdp	case lang_input_section_enum:
84333965Sjdp	case lang_input_statement_enum:
84433965Sjdp	case lang_assignment_statement_enum:
84533965Sjdp	case lang_padding_statement_enum:
84633965Sjdp	case lang_address_statement_enum:
84733965Sjdp	case lang_fill_statement_enum:
84833965Sjdp	  break;
84933965Sjdp	default:
85033965Sjdp	  FAIL ();
85133965Sjdp	  break;
85233965Sjdp	}
85333965Sjdp    }
85433965Sjdp}
85533965Sjdp
85633965Sjdpvoid
857130561Sobrienlang_for_each_statement (void (*func) (lang_statement_union_type *))
85833965Sjdp{
85977298Sobrien  lang_for_each_statement_worker (func, statement_list.head);
86033965Sjdp}
86133965Sjdp
86233965Sjdp/*----------------------------------------------------------------------*/
86377298Sobrien
86433965Sjdpvoid
865130561Sobrienlang_list_init (lang_statement_list_type *list)
86633965Sjdp{
867130561Sobrien  list->head = NULL;
86833965Sjdp  list->tail = &list->head;
86933965Sjdp}
87033965Sjdp
87177298Sobrien/* Build a new statement node for the parse tree.  */
87233965Sjdp
87377298Sobrienstatic lang_statement_union_type *
874130561Sobriennew_statement (enum statement_enum type,
875130561Sobrien	       size_t size,
876130561Sobrien	       lang_statement_list_type *list)
87733965Sjdp{
878130561Sobrien  lang_statement_union_type *new;
87933965Sjdp
880130561Sobrien  new = stat_alloc (size);
88133965Sjdp  new->header.type = type;
882130561Sobrien  new->header.next = NULL;
88333965Sjdp  lang_statement_append (list, new, &new->header.next);
88433965Sjdp  return new;
88533965Sjdp}
88633965Sjdp
88777298Sobrien/* Build a new input file node for the language.  There are several
88877298Sobrien   ways in which we treat an input file, eg, we only look at symbols,
88977298Sobrien   or prefix it with a -l etc.
89033965Sjdp
89177298Sobrien   We can be supplied with requests for input files more than once;
892130561Sobrien   they may, for example be split over several lines like foo.o(.text)
89378828Sobrien   foo.o(.data) etc, so when asked for a file we check that we haven't
89477298Sobrien   got it already so we don't duplicate the bfd.  */
89533965Sjdp
89633965Sjdpstatic lang_input_statement_type *
897130561Sobriennew_afile (const char *name,
898130561Sobrien	   lang_input_file_enum_type file_type,
899130561Sobrien	   const char *target,
900130561Sobrien	   bfd_boolean add_to_list)
90133965Sjdp{
90233965Sjdp  lang_input_statement_type *p;
90333965Sjdp
90433965Sjdp  if (add_to_list)
90533965Sjdp    p = new_stat (lang_input_statement, stat_ptr);
90633965Sjdp  else
90733965Sjdp    {
908130561Sobrien      p = stat_alloc (sizeof (lang_input_statement_type));
909218822Sdim      p->header.type = lang_input_statement_enum;
91033965Sjdp      p->header.next = NULL;
91133965Sjdp    }
91233965Sjdp
913130561Sobrien  lang_has_input_file = TRUE;
91433965Sjdp  p->target = target;
915130561Sobrien  p->sysrooted = FALSE;
916218822Sdim
917218822Sdim  if (file_type == lang_input_file_is_l_enum
918218822Sdim      && name[0] == ':' && name[1] != '\0')
919218822Sdim    {
920218822Sdim      file_type = lang_input_file_is_search_file_enum;
921218822Sdim      name = name + 1;
922218822Sdim    }
923218822Sdim
92433965Sjdp  switch (file_type)
92533965Sjdp    {
92633965Sjdp    case lang_input_file_is_symbols_only_enum:
92733965Sjdp      p->filename = name;
928130561Sobrien      p->is_archive = FALSE;
929130561Sobrien      p->real = TRUE;
93033965Sjdp      p->local_sym_name = name;
931130561Sobrien      p->just_syms_flag = TRUE;
932130561Sobrien      p->search_dirs_flag = FALSE;
93333965Sjdp      break;
93433965Sjdp    case lang_input_file_is_fake_enum:
93533965Sjdp      p->filename = name;
936130561Sobrien      p->is_archive = FALSE;
937130561Sobrien      p->real = FALSE;
93833965Sjdp      p->local_sym_name = name;
939130561Sobrien      p->just_syms_flag = FALSE;
940130561Sobrien      p->search_dirs_flag = FALSE;
94133965Sjdp      break;
94233965Sjdp    case lang_input_file_is_l_enum:
943130561Sobrien      p->is_archive = TRUE;
94433965Sjdp      p->filename = name;
945130561Sobrien      p->real = TRUE;
946130561Sobrien      p->local_sym_name = concat ("-l", name, NULL);
947130561Sobrien      p->just_syms_flag = FALSE;
948130561Sobrien      p->search_dirs_flag = TRUE;
94933965Sjdp      break;
95033965Sjdp    case lang_input_file_is_marker_enum:
95133965Sjdp      p->filename = name;
952130561Sobrien      p->is_archive = FALSE;
953130561Sobrien      p->real = FALSE;
95433965Sjdp      p->local_sym_name = name;
955130561Sobrien      p->just_syms_flag = FALSE;
956130561Sobrien      p->search_dirs_flag = TRUE;
95733965Sjdp      break;
95833965Sjdp    case lang_input_file_is_search_file_enum:
959130561Sobrien      p->sysrooted = ldlang_sysrooted_script;
96033965Sjdp      p->filename = name;
961130561Sobrien      p->is_archive = FALSE;
962130561Sobrien      p->real = TRUE;
96333965Sjdp      p->local_sym_name = name;
964130561Sobrien      p->just_syms_flag = FALSE;
965130561Sobrien      p->search_dirs_flag = TRUE;
96633965Sjdp      break;
96733965Sjdp    case lang_input_file_is_file_enum:
96833965Sjdp      p->filename = name;
969130561Sobrien      p->is_archive = FALSE;
970130561Sobrien      p->real = TRUE;
97133965Sjdp      p->local_sym_name = name;
972130561Sobrien      p->just_syms_flag = FALSE;
973130561Sobrien      p->search_dirs_flag = FALSE;
97433965Sjdp      break;
97533965Sjdp    default:
97633965Sjdp      FAIL ();
97733965Sjdp    }
978130561Sobrien  p->the_bfd = NULL;
979130561Sobrien  p->asymbols = NULL;
980130561Sobrien  p->next_real_file = NULL;
981130561Sobrien  p->next = NULL;
98233965Sjdp  p->symbol_count = 0;
98333965Sjdp  p->dynamic = config.dynamic_link;
984218822Sdim  p->add_needed = add_needed;
985130561Sobrien  p->as_needed = as_needed;
98633965Sjdp  p->whole_archive = whole_archive;
987130561Sobrien  p->loaded = FALSE;
98833965Sjdp  lang_statement_append (&input_file_chain,
98933965Sjdp			 (lang_statement_union_type *) p,
99033965Sjdp			 &p->next_real_file);
99133965Sjdp  return p;
99233965Sjdp}
99333965Sjdp
99433965Sjdplang_input_statement_type *
995130561Sobrienlang_add_input_file (const char *name,
996130561Sobrien		     lang_input_file_enum_type file_type,
997130561Sobrien		     const char *target)
99833965Sjdp{
999130561Sobrien  return new_afile (name, file_type, target, TRUE);
100033965Sjdp}
100133965Sjdp
1002218822Sdimstruct out_section_hash_entry
1003218822Sdim{
1004218822Sdim  struct bfd_hash_entry root;
1005218822Sdim  lang_statement_union_type s;
1006218822Sdim};
1007218822Sdim
1008218822Sdim/* The hash table.  */
1009218822Sdim
1010218822Sdimstatic struct bfd_hash_table output_section_statement_table;
1011218822Sdim
1012218822Sdim/* Support routines for the hash table used by lang_output_section_find,
1013218822Sdim   initialize the table, fill in an entry and remove the table.  */
1014218822Sdim
1015218822Sdimstatic struct bfd_hash_entry *
1016218822Sdimoutput_section_statement_newfunc (struct bfd_hash_entry *entry,
1017218822Sdim				  struct bfd_hash_table *table,
1018218822Sdim				  const char *string)
1019218822Sdim{
1020218822Sdim  lang_output_section_statement_type **nextp;
1021218822Sdim  struct out_section_hash_entry *ret;
1022218822Sdim
1023218822Sdim  if (entry == NULL)
1024218822Sdim    {
1025218822Sdim      entry = bfd_hash_allocate (table, sizeof (*ret));
1026218822Sdim      if (entry == NULL)
1027218822Sdim	return entry;
1028218822Sdim    }
1029218822Sdim
1030218822Sdim  entry = bfd_hash_newfunc (entry, table, string);
1031218822Sdim  if (entry == NULL)
1032218822Sdim    return entry;
1033218822Sdim
1034218822Sdim  ret = (struct out_section_hash_entry *) entry;
1035218822Sdim  memset (&ret->s, 0, sizeof (ret->s));
1036218822Sdim  ret->s.header.type = lang_output_section_statement_enum;
1037218822Sdim  ret->s.output_section_statement.subsection_alignment = -1;
1038218822Sdim  ret->s.output_section_statement.section_alignment = -1;
1039218822Sdim  ret->s.output_section_statement.block_value = 1;
1040218822Sdim  lang_list_init (&ret->s.output_section_statement.children);
1041218822Sdim  lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next);
1042218822Sdim
1043218822Sdim  /* For every output section statement added to the list, except the
1044218822Sdim     first one, lang_output_section_statement.tail points to the "next"
1045218822Sdim     field of the last element of the list.  */
1046218822Sdim  if (lang_output_section_statement.head != NULL)
1047218822Sdim    ret->s.output_section_statement.prev
1048218822Sdim      = ((lang_output_section_statement_type *)
1049218822Sdim	 ((char *) lang_output_section_statement.tail
1050218822Sdim	  - offsetof (lang_output_section_statement_type, next)));
1051218822Sdim
1052218822Sdim  /* GCC's strict aliasing rules prevent us from just casting the
1053218822Sdim     address, so we store the pointer in a variable and cast that
1054218822Sdim     instead.  */
1055218822Sdim  nextp = &ret->s.output_section_statement.next;
1056218822Sdim  lang_statement_append (&lang_output_section_statement,
1057218822Sdim			 &ret->s,
1058218822Sdim			 (lang_statement_union_type **) nextp);
1059218822Sdim  return &ret->root;
1060218822Sdim}
1061218822Sdim
1062218822Sdimstatic void
1063218822Sdimoutput_section_statement_table_init (void)
1064218822Sdim{
1065218822Sdim  if (!bfd_hash_table_init_n (&output_section_statement_table,
1066218822Sdim			      output_section_statement_newfunc,
1067218822Sdim			      sizeof (struct out_section_hash_entry),
1068218822Sdim			      61))
1069218822Sdim    einfo (_("%P%F: can not create hash table: %E\n"));
1070218822Sdim}
1071218822Sdim
1072218822Sdimstatic void
1073218822Sdimoutput_section_statement_table_free (void)
1074218822Sdim{
1075218822Sdim  bfd_hash_table_free (&output_section_statement_table);
1076218822Sdim}
1077218822Sdim
107877298Sobrien/* Build enough state so that the parser can build its tree.  */
107977298Sobrien
108033965Sjdpvoid
1081130561Sobrienlang_init (void)
108233965Sjdp{
108333965Sjdp  obstack_begin (&stat_obstack, 1000);
108433965Sjdp
108533965Sjdp  stat_ptr = &statement_list;
108633965Sjdp
1087218822Sdim  output_section_statement_table_init ();
1088218822Sdim
108933965Sjdp  lang_list_init (stat_ptr);
109033965Sjdp
109133965Sjdp  lang_list_init (&input_file_chain);
109233965Sjdp  lang_list_init (&lang_output_section_statement);
109333965Sjdp  lang_list_init (&file_chain);
1094130561Sobrien  first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
1095130561Sobrien				    NULL);
109677298Sobrien  abs_output_section =
109777298Sobrien    lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
109833965Sjdp
109933965Sjdp  abs_output_section->bfd_section = bfd_abs_section_ptr;
110033965Sjdp
1101130561Sobrien  /* The value "3" is ad-hoc, somewhat related to the expected number of
1102130561Sobrien     DEFINED expressions in a linker script.  For most default linker
1103130561Sobrien     scripts, there are none.  Why a hash table then?  Well, it's somewhat
1104130561Sobrien     simpler to re-use working machinery than using a linked list in terms
1105130561Sobrien     of code-complexity here in ld, besides the initialization which just
1106130561Sobrien     looks like other code here.  */
1107218822Sdim  if (!bfd_hash_table_init_n (&lang_definedness_table,
1108218822Sdim			      lang_definedness_newfunc,
1109218822Sdim			      sizeof (struct lang_definedness_hash_entry),
1110218822Sdim			      3))
1111218822Sdim    einfo (_("%P%F: can not create hash table: %E\n"));
1112218822Sdim}
1113130561Sobrien
1114218822Sdimvoid
1115218822Sdimlang_finish (void)
1116218822Sdim{
1117218822Sdim  output_section_statement_table_free ();
111833965Sjdp}
111933965Sjdp
112033965Sjdp/*----------------------------------------------------------------------
112177298Sobrien  A region is an area of memory declared with the
112277298Sobrien  MEMORY {  name:org=exp, len=exp ... }
112377298Sobrien  syntax.
112433965Sjdp
112577298Sobrien  We maintain a list of all the regions here.
112633965Sjdp
112777298Sobrien  If no regions are specified in the script, then the default is used
1128130561Sobrien  which is created when looked up to be the entire data space.
112933965Sjdp
1130130561Sobrien  If create is true we are creating a region inside a MEMORY block.
1131130561Sobrien  In this case it is probably an error to create a region that has
1132130561Sobrien  already been created.  If we are not inside a MEMORY block it is
1133130561Sobrien  dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION)
1134130561Sobrien  and so we issue a warning.  */
1135130561Sobrien
113633965Sjdpstatic lang_memory_region_type *lang_memory_region_list;
1137218822Sdimstatic lang_memory_region_type **lang_memory_region_list_tail
1138218822Sdim  = &lang_memory_region_list;
113933965Sjdp
114033965Sjdplang_memory_region_type *
1141130561Sobrienlang_memory_region_lookup (const char *const name, bfd_boolean create)
114233965Sjdp{
114338889Sjdp  lang_memory_region_type *p;
1144130561Sobrien  lang_memory_region_type *new;
114533965Sjdp
1146104834Sobrien  /* NAME is NULL for LMA memspecs if no region was specified.  */
1147104834Sobrien  if (name == NULL)
1148104834Sobrien    return NULL;
1149104834Sobrien
1150130561Sobrien  for (p = lang_memory_region_list; p != NULL; p = p->next)
1151130561Sobrien    if (strcmp (p->name, name) == 0)
1152130561Sobrien      {
1153130561Sobrien	if (create)
1154218822Sdim	  einfo (_("%P:%S: warning: redeclaration of memory region '%s'\n"),
1155218822Sdim		 name);
1156130561Sobrien	return p;
1157130561Sobrien      }
115833965Sjdp
1159130561Sobrien  if (!create && strcmp (name, DEFAULT_MEMORY_REGION))
1160130561Sobrien    einfo (_("%P:%S: warning: memory region %s not declared\n"), name);
116133965Sjdp
1162130561Sobrien  new = stat_alloc (sizeof (lang_memory_region_type));
116333965Sjdp
1164130561Sobrien  new->name = xstrdup (name);
1165130561Sobrien  new->next = NULL;
1166130561Sobrien  new->origin = 0;
1167218822Sdim  new->length = ~(bfd_size_type) 0;
1168218822Sdim  new->current = 0;
1169218822Sdim  new->last_os = NULL;
1170130561Sobrien  new->flags = 0;
1171130561Sobrien  new->not_flags = 0;
1172130561Sobrien  new->had_full_message = FALSE;
1173130561Sobrien
1174218822Sdim  *lang_memory_region_list_tail = new;
1175218822Sdim  lang_memory_region_list_tail = &new->next;
1176218822Sdim
1177130561Sobrien  return new;
117833965Sjdp}
117933965Sjdp
118077298Sobrienstatic lang_memory_region_type *
1181130561Sobrienlang_memory_default (asection *section)
118238889Sjdp{
118338889Sjdp  lang_memory_region_type *p;
118438889Sjdp
118538889Sjdp  flagword sec_flags = section->flags;
118638889Sjdp
118738889Sjdp  /* Override SEC_DATA to mean a writable section.  */
118838889Sjdp  if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC)
118938889Sjdp    sec_flags |= SEC_DATA;
119038889Sjdp
1191130561Sobrien  for (p = lang_memory_region_list; p != NULL; p = p->next)
119238889Sjdp    {
119338889Sjdp      if ((p->flags & sec_flags) != 0
119438889Sjdp	  && (p->not_flags & sec_flags) == 0)
119538889Sjdp	{
119638889Sjdp	  return p;
119738889Sjdp	}
119838889Sjdp    }
1199130561Sobrien  return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
120038889Sjdp}
120138889Sjdp
120233965Sjdplang_output_section_statement_type *
1203130561Sobrienlang_output_section_find (const char *const name)
120433965Sjdp{
1205218822Sdim  struct out_section_hash_entry *entry;
1206218822Sdim  unsigned long hash;
120733965Sjdp
1208218822Sdim  entry = ((struct out_section_hash_entry *)
1209218822Sdim	   bfd_hash_lookup (&output_section_statement_table, name,
1210218822Sdim			    FALSE, FALSE));
1211218822Sdim  if (entry == NULL)
1212218822Sdim    return NULL;
1213218822Sdim
1214218822Sdim  hash = entry->root.hash;
1215218822Sdim  do
121633965Sjdp    {
1217218822Sdim      if (entry->s.output_section_statement.constraint != -1)
1218218822Sdim	return &entry->s.output_section_statement;
1219218822Sdim      entry = (struct out_section_hash_entry *) entry->root.next;
122033965Sjdp    }
1221218822Sdim  while (entry != NULL
1222218822Sdim	 && entry->root.hash == hash
1223218822Sdim	 && strcmp (name, entry->s.output_section_statement.name) == 0);
1224218822Sdim
1225130561Sobrien  return NULL;
122633965Sjdp}
122733965Sjdp
1228218822Sdimstatic lang_output_section_statement_type *
1229218822Sdimlang_output_section_statement_lookup_1 (const char *const name, int constraint)
1230218822Sdim{
1231218822Sdim  struct out_section_hash_entry *entry;
1232218822Sdim  struct out_section_hash_entry *last_ent;
1233218822Sdim  unsigned long hash;
1234218822Sdim
1235218822Sdim  entry = ((struct out_section_hash_entry *)
1236218822Sdim	   bfd_hash_lookup (&output_section_statement_table, name,
1237218822Sdim			    TRUE, FALSE));
1238218822Sdim  if (entry == NULL)
1239218822Sdim    {
1240218822Sdim      einfo (_("%P%F: failed creating section `%s': %E\n"), name);
1241218822Sdim      return NULL;
1242218822Sdim    }
1243218822Sdim
1244218822Sdim  if (entry->s.output_section_statement.name != NULL)
1245218822Sdim    {
1246218822Sdim      /* We have a section of this name, but it might not have the correct
1247218822Sdim	 constraint.  */
1248218822Sdim      hash = entry->root.hash;
1249218822Sdim      do
1250218822Sdim	{
1251218822Sdim	  if (entry->s.output_section_statement.constraint != -1
1252218822Sdim	      && (constraint == 0
1253218822Sdim		  || (constraint == entry->s.output_section_statement.constraint
1254218822Sdim		      && constraint != SPECIAL)))
1255218822Sdim	    return &entry->s.output_section_statement;
1256218822Sdim	  last_ent = entry;
1257218822Sdim	  entry = (struct out_section_hash_entry *) entry->root.next;
1258218822Sdim	}
1259218822Sdim      while (entry != NULL
1260218822Sdim	     && entry->root.hash == hash
1261218822Sdim	     && strcmp (name, entry->s.output_section_statement.name) == 0);
1262218822Sdim
1263218822Sdim      entry
1264218822Sdim	= ((struct out_section_hash_entry *)
1265218822Sdim	   output_section_statement_newfunc (NULL,
1266218822Sdim					     &output_section_statement_table,
1267218822Sdim					     name));
1268218822Sdim      if (entry == NULL)
1269218822Sdim	{
1270218822Sdim	  einfo (_("%P%F: failed creating section `%s': %E\n"), name);
1271218822Sdim	  return NULL;
1272218822Sdim	}
1273218822Sdim      entry->root = last_ent->root;
1274218822Sdim      last_ent->root.next = &entry->root;
1275218822Sdim    }
1276218822Sdim
1277218822Sdim  entry->s.output_section_statement.name = name;
1278218822Sdim  entry->s.output_section_statement.constraint = constraint;
1279218822Sdim  return &entry->s.output_section_statement;
1280218822Sdim}
1281218822Sdim
128233965Sjdplang_output_section_statement_type *
1283130561Sobrienlang_output_section_statement_lookup (const char *const name)
128433965Sjdp{
1285218822Sdim  return lang_output_section_statement_lookup_1 (name, 0);
1286218822Sdim}
1287218822Sdim
1288218822Sdim/* A variant of lang_output_section_find used by place_orphan.
1289218822Sdim   Returns the output statement that should precede a new output
1290218822Sdim   statement for SEC.  If an exact match is found on certain flags,
1291218822Sdim   sets *EXACT too.  */
1292218822Sdim
1293218822Sdimlang_output_section_statement_type *
1294218822Sdimlang_output_section_find_by_flags (const asection *sec,
1295218822Sdim				   lang_output_section_statement_type **exact,
1296218822Sdim				   lang_match_sec_type_func match_type)
1297218822Sdim{
1298218822Sdim  lang_output_section_statement_type *first, *look, *found;
1299218822Sdim  flagword flags;
1300218822Sdim
1301218822Sdim  /* We know the first statement on this list is *ABS*.  May as well
1302218822Sdim     skip it.  */
1303218822Sdim  first = &lang_output_section_statement.head->output_section_statement;
1304218822Sdim  first = first->next;
1305218822Sdim
1306218822Sdim  /* First try for an exact match.  */
1307218822Sdim  found = NULL;
1308218822Sdim  for (look = first; look; look = look->next)
1309218822Sdim    {
1310218822Sdim      flags = look->flags;
1311218822Sdim      if (look->bfd_section != NULL)
1312218822Sdim	{
1313218822Sdim	  flags = look->bfd_section->flags;
1314218822Sdim	  if (match_type && !match_type (output_bfd, look->bfd_section,
1315218822Sdim					 sec->owner, sec))
1316218822Sdim	    continue;
1317218822Sdim	}
1318218822Sdim      flags ^= sec->flags;
1319218822Sdim      if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1320218822Sdim		     | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
1321218822Sdim	found = look;
1322218822Sdim    }
1323218822Sdim  if (found != NULL)
1324218822Sdim    {
1325218822Sdim      if (exact != NULL)
1326218822Sdim	*exact = found;
1327218822Sdim      return found;
1328218822Sdim    }
1329218822Sdim
1330218822Sdim  if (sec->flags & SEC_CODE)
1331218822Sdim    {
1332218822Sdim      /* Try for a rw code section.  */
1333218822Sdim      for (look = first; look; look = look->next)
1334218822Sdim	{
1335218822Sdim	  flags = look->flags;
1336218822Sdim	  if (look->bfd_section != NULL)
1337218822Sdim	    {
1338218822Sdim	      flags = look->bfd_section->flags;
1339218822Sdim	      if (match_type && !match_type (output_bfd, look->bfd_section,
1340218822Sdim					     sec->owner, sec))
1341218822Sdim		continue;
1342218822Sdim	    }
1343218822Sdim	  flags ^= sec->flags;
1344218822Sdim	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
1345218822Sdim			 | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
1346218822Sdim	    found = look;
1347218822Sdim	}
1348218822Sdim    }
1349218822Sdim  else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
1350218822Sdim    {
1351218822Sdim      /* .rodata can go after .text, .sdata2 after .rodata.  */
1352218822Sdim      for (look = first; look; look = look->next)
1353218822Sdim	{
1354218822Sdim	  flags = look->flags;
1355218822Sdim	  if (look->bfd_section != NULL)
1356218822Sdim	    {
1357218822Sdim	      flags = look->bfd_section->flags;
1358218822Sdim	      if (match_type && !match_type (output_bfd, look->bfd_section,
1359218822Sdim					     sec->owner, sec))
1360218822Sdim		continue;
1361218822Sdim	    }
1362218822Sdim	  flags ^= sec->flags;
1363218822Sdim	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
1364218822Sdim			 | SEC_READONLY))
1365218822Sdim	      && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
1366218822Sdim	    found = look;
1367218822Sdim	}
1368218822Sdim    }
1369218822Sdim  else if (sec->flags & SEC_SMALL_DATA)
1370218822Sdim    {
1371218822Sdim      /* .sdata goes after .data, .sbss after .sdata.  */
1372218822Sdim      for (look = first; look; look = look->next)
1373218822Sdim	{
1374218822Sdim	  flags = look->flags;
1375218822Sdim	  if (look->bfd_section != NULL)
1376218822Sdim	    {
1377218822Sdim	      flags = look->bfd_section->flags;
1378218822Sdim	      if (match_type && !match_type (output_bfd, look->bfd_section,
1379218822Sdim					     sec->owner, sec))
1380218822Sdim		continue;
1381218822Sdim	    }
1382218822Sdim	  flags ^= sec->flags;
1383218822Sdim	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
1384218822Sdim			 | SEC_THREAD_LOCAL))
1385218822Sdim	      || ((look->flags & SEC_SMALL_DATA)
1386218822Sdim		  && !(sec->flags & SEC_HAS_CONTENTS)))
1387218822Sdim	    found = look;
1388218822Sdim	}
1389218822Sdim    }
1390218822Sdim  else if (sec->flags & SEC_HAS_CONTENTS)
1391218822Sdim    {
1392218822Sdim      /* .data goes after .rodata.  */
1393218822Sdim      for (look = first; look; look = look->next)
1394218822Sdim	{
1395218822Sdim	  flags = look->flags;
1396218822Sdim	  if (look->bfd_section != NULL)
1397218822Sdim	    {
1398218822Sdim	      flags = look->bfd_section->flags;
1399218822Sdim	      if (match_type && !match_type (output_bfd, look->bfd_section,
1400218822Sdim					     sec->owner, sec))
1401218822Sdim		continue;
1402218822Sdim	    }
1403218822Sdim	  flags ^= sec->flags;
1404218822Sdim	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
1405218822Sdim			 | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
1406218822Sdim	    found = look;
1407218822Sdim	}
1408218822Sdim    }
1409218822Sdim  else
1410218822Sdim    {
1411218822Sdim      /* .bss goes last.  */
1412218822Sdim      for (look = first; look; look = look->next)
1413218822Sdim	{
1414218822Sdim	  flags = look->flags;
1415218822Sdim	  if (look->bfd_section != NULL)
1416218822Sdim	    {
1417218822Sdim	      flags = look->bfd_section->flags;
1418218822Sdim	      if (match_type && !match_type (output_bfd, look->bfd_section,
1419218822Sdim					     sec->owner, sec))
1420218822Sdim		continue;
1421218822Sdim	    }
1422218822Sdim	  flags ^= sec->flags;
1423218822Sdim	  if (!(flags & SEC_ALLOC))
1424218822Sdim	    found = look;
1425218822Sdim	}
1426218822Sdim    }
1427218822Sdim
1428218822Sdim  if (found || !match_type)
1429218822Sdim    return found;
1430218822Sdim
1431218822Sdim  return lang_output_section_find_by_flags (sec, NULL, NULL);
1432218822Sdim}
1433218822Sdim
1434218822Sdim/* Find the last output section before given output statement.
1435218822Sdim   Used by place_orphan.  */
1436218822Sdim
1437218822Sdimstatic asection *
1438218822Sdimoutput_prev_sec_find (lang_output_section_statement_type *os)
1439218822Sdim{
144033965Sjdp  lang_output_section_statement_type *lookup;
144133965Sjdp
1442218822Sdim  for (lookup = os->prev; lookup != NULL; lookup = lookup->prev)
144333965Sjdp    {
1444218822Sdim      if (lookup->constraint == -1)
1445218822Sdim	continue;
144633965Sjdp
1447218822Sdim      if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
1448218822Sdim	return lookup->bfd_section;
1449218822Sdim    }
145033965Sjdp
1451218822Sdim  return NULL;
1452218822Sdim}
145333965Sjdp
1454218822Sdimlang_output_section_statement_type *
1455218822Sdimlang_insert_orphan (asection *s,
1456218822Sdim		    const char *secname,
1457218822Sdim		    lang_output_section_statement_type *after,
1458218822Sdim		    struct orphan_save *place,
1459218822Sdim		    etree_type *address,
1460218822Sdim		    lang_statement_list_type *add_child)
1461218822Sdim{
1462218822Sdim  lang_statement_list_type *old;
1463218822Sdim  lang_statement_list_type add;
1464218822Sdim  const char *ps;
1465218822Sdim  lang_output_section_statement_type *os;
1466218822Sdim  lang_output_section_statement_type **os_tail;
1467218822Sdim
1468218822Sdim  /* Start building a list of statements for this section.
1469218822Sdim     First save the current statement pointer.  */
1470218822Sdim  old = stat_ptr;
1471218822Sdim
1472218822Sdim  /* If we have found an appropriate place for the output section
1473218822Sdim     statements for this orphan, add them to our own private list,
1474218822Sdim     inserting them later into the global statement list.  */
1475218822Sdim  if (after != NULL)
1476218822Sdim    {
1477218822Sdim      stat_ptr = &add;
1478218822Sdim      lang_list_init (stat_ptr);
147933965Sjdp    }
1480218822Sdim
1481218822Sdim  if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
1482218822Sdim    address = exp_intop (0);
1483218822Sdim
1484218822Sdim  os_tail = ((lang_output_section_statement_type **)
1485218822Sdim	     lang_output_section_statement.tail);
1486218822Sdim  os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
1487218822Sdim					    NULL, 0);
1488218822Sdim
1489218822Sdim  ps = NULL;
1490218822Sdim  if (config.build_constructors && *os_tail == os)
1491218822Sdim    {
1492218822Sdim      /* If the name of the section is representable in C, then create
1493218822Sdim	 symbols to mark the start and the end of the section.  */
1494218822Sdim      for (ps = secname; *ps != '\0'; ps++)
1495218822Sdim	if (! ISALNUM ((unsigned char) *ps) && *ps != '_')
1496218822Sdim	  break;
1497218822Sdim      if (*ps == '\0')
1498218822Sdim	{
1499218822Sdim	  char *symname;
1500218822Sdim	  etree_type *e_align;
1501218822Sdim
1502218822Sdim	  symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
1503218822Sdim	  symname[0] = bfd_get_symbol_leading_char (output_bfd);
1504218822Sdim	  sprintf (symname + (symname[0] != 0), "__start_%s", secname);
1505218822Sdim	  e_align = exp_unop (ALIGN_K,
1506218822Sdim			      exp_intop ((bfd_vma) 1 << s->alignment_power));
1507218822Sdim	  lang_add_assignment (exp_assop ('=', ".", e_align));
1508218822Sdim	  lang_add_assignment (exp_provide (symname,
1509218822Sdim					    exp_unop (ABSOLUTE,
1510218822Sdim						      exp_nameop (NAME, ".")),
1511218822Sdim					    FALSE));
1512218822Sdim	}
1513218822Sdim    }
1514218822Sdim
1515218822Sdim  if (add_child == NULL)
1516218822Sdim    add_child = &os->children;
1517218822Sdim  lang_add_section (add_child, s, os);
1518218822Sdim
1519218822Sdim  lang_leave_output_section_statement (0, "*default*", NULL, NULL);
1520218822Sdim
1521218822Sdim  if (ps != NULL && *ps == '\0')
1522218822Sdim    {
1523218822Sdim      char *symname;
1524218822Sdim
1525218822Sdim      /* lang_leave_ouput_section_statement resets stat_ptr.
1526218822Sdim	 Put stat_ptr back where we want it.  */
1527218822Sdim      if (after != NULL)
1528218822Sdim	stat_ptr = &add;
1529218822Sdim
1530218822Sdim      symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
1531218822Sdim      symname[0] = bfd_get_symbol_leading_char (output_bfd);
1532218822Sdim      sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
1533218822Sdim      lang_add_assignment (exp_provide (symname,
1534218822Sdim					exp_nameop (NAME, "."),
1535218822Sdim					FALSE));
1536218822Sdim    }
1537218822Sdim
1538218822Sdim  /* Restore the global list pointer.  */
1539218822Sdim  if (after != NULL)
1540218822Sdim    stat_ptr = old;
1541218822Sdim
1542218822Sdim  if (after != NULL && os->bfd_section != NULL)
1543218822Sdim    {
1544218822Sdim      asection *snew, *as;
1545218822Sdim
1546218822Sdim      snew = os->bfd_section;
1547218822Sdim
1548218822Sdim      /* Shuffle the bfd section list to make the output file look
1549218822Sdim	 neater.  This is really only cosmetic.  */
1550218822Sdim      if (place->section == NULL
1551218822Sdim	  && after != (&lang_output_section_statement.head
1552218822Sdim		       ->output_section_statement))
1553218822Sdim	{
1554218822Sdim	  asection *bfd_section = after->bfd_section;
1555218822Sdim
1556218822Sdim	  /* If the output statement hasn't been used to place any input
1557218822Sdim	     sections (and thus doesn't have an output bfd_section),
1558218822Sdim	     look for the closest prior output statement having an
1559218822Sdim	     output section.  */
1560218822Sdim	  if (bfd_section == NULL)
1561218822Sdim	    bfd_section = output_prev_sec_find (after);
1562218822Sdim
1563218822Sdim	  if (bfd_section != NULL && bfd_section != snew)
1564218822Sdim	    place->section = &bfd_section->next;
1565218822Sdim	}
1566218822Sdim
1567218822Sdim      if (place->section == NULL)
1568218822Sdim	place->section = &output_bfd->sections;
1569218822Sdim
1570218822Sdim      as = *place->section;
1571218822Sdim
1572218822Sdim      if (!as)
1573218822Sdim	{
1574218822Sdim	  /* Put the section at the end of the list.  */
1575218822Sdim
1576218822Sdim	  /* Unlink the section.  */
1577218822Sdim	  bfd_section_list_remove (output_bfd, snew);
1578218822Sdim
1579218822Sdim	  /* Now tack it back on in the right place.  */
1580218822Sdim	  bfd_section_list_append (output_bfd, snew);
1581218822Sdim	}
1582218822Sdim      else if (as != snew && as->prev != snew)
1583218822Sdim	{
1584218822Sdim	  /* Unlink the section.  */
1585218822Sdim	  bfd_section_list_remove (output_bfd, snew);
1586218822Sdim
1587218822Sdim	  /* Now tack it back on in the right place.  */
1588218822Sdim	  bfd_section_list_insert_before (output_bfd, as, snew);
1589218822Sdim	}
1590218822Sdim
1591218822Sdim      /* Save the end of this list.  Further ophans of this type will
1592218822Sdim	 follow the one we've just added.  */
1593218822Sdim      place->section = &snew->next;
1594218822Sdim
1595218822Sdim      /* The following is non-cosmetic.  We try to put the output
1596218822Sdim	 statements in some sort of reasonable order here, because they
1597218822Sdim	 determine the final load addresses of the orphan sections.
1598218822Sdim	 In addition, placing output statements in the wrong order may
1599218822Sdim	 require extra segments.  For instance, given a typical
1600218822Sdim	 situation of all read-only sections placed in one segment and
1601218822Sdim	 following that a segment containing all the read-write
1602218822Sdim	 sections, we wouldn't want to place an orphan read/write
1603218822Sdim	 section before or amongst the read-only ones.  */
1604218822Sdim      if (add.head != NULL)
1605218822Sdim	{
1606218822Sdim	  lang_output_section_statement_type *newly_added_os;
1607218822Sdim
1608218822Sdim	  if (place->stmt == NULL)
1609218822Sdim	    {
1610218822Sdim	      lang_statement_union_type **where;
1611218822Sdim	      lang_statement_union_type **assign = NULL;
1612218822Sdim	      bfd_boolean ignore_first;
1613218822Sdim
1614218822Sdim	      /* Look for a suitable place for the new statement list.
1615218822Sdim		 The idea is to skip over anything that might be inside
1616218822Sdim		 a SECTIONS {} statement in a script, before we find
1617218822Sdim		 another output_section_statement.  Assignments to "dot"
1618218822Sdim		 before an output section statement are assumed to
1619218822Sdim		 belong to it.  An exception to this rule is made for
1620218822Sdim		 the first assignment to dot, otherwise we might put an
1621218822Sdim		 orphan before . = . + SIZEOF_HEADERS or similar
1622218822Sdim		 assignments that set the initial address.  */
1623218822Sdim
1624218822Sdim	      ignore_first = after == (&lang_output_section_statement.head
1625218822Sdim				       ->output_section_statement);
1626218822Sdim	      for (where = &after->header.next;
1627218822Sdim		   *where != NULL;
1628218822Sdim		   where = &(*where)->header.next)
1629218822Sdim		{
1630218822Sdim		  switch ((*where)->header.type)
1631218822Sdim		    {
1632218822Sdim		    case lang_assignment_statement_enum:
1633218822Sdim		      if (assign == NULL)
1634218822Sdim			{
1635218822Sdim			  lang_assignment_statement_type *ass;
1636218822Sdim			  ass = &(*where)->assignment_statement;
1637218822Sdim			  if (ass->exp->type.node_class != etree_assert
1638218822Sdim			      && ass->exp->assign.dst[0] == '.'
1639218822Sdim			      && ass->exp->assign.dst[1] == 0
1640218822Sdim			      && !ignore_first)
1641218822Sdim			    assign = where;
1642218822Sdim			}
1643218822Sdim		      ignore_first = FALSE;
1644218822Sdim		      continue;
1645218822Sdim		    case lang_wild_statement_enum:
1646218822Sdim		    case lang_input_section_enum:
1647218822Sdim		    case lang_object_symbols_statement_enum:
1648218822Sdim		    case lang_fill_statement_enum:
1649218822Sdim		    case lang_data_statement_enum:
1650218822Sdim		    case lang_reloc_statement_enum:
1651218822Sdim		    case lang_padding_statement_enum:
1652218822Sdim		    case lang_constructors_statement_enum:
1653218822Sdim		      assign = NULL;
1654218822Sdim		      continue;
1655218822Sdim		    case lang_output_section_statement_enum:
1656218822Sdim		      if (assign != NULL)
1657218822Sdim			where = assign;
1658218822Sdim		    case lang_input_statement_enum:
1659218822Sdim		    case lang_address_statement_enum:
1660218822Sdim		    case lang_target_statement_enum:
1661218822Sdim		    case lang_output_statement_enum:
1662218822Sdim		    case lang_group_statement_enum:
1663218822Sdim		    case lang_afile_asection_pair_statement_enum:
1664218822Sdim		      break;
1665218822Sdim		    }
1666218822Sdim		  break;
1667218822Sdim		}
1668218822Sdim
1669218822Sdim	      *add.tail = *where;
1670218822Sdim	      *where = add.head;
1671218822Sdim
1672218822Sdim	      place->os_tail = &after->next;
1673218822Sdim	    }
1674218822Sdim	  else
1675218822Sdim	    {
1676218822Sdim	      /* Put it after the last orphan statement we added.  */
1677218822Sdim	      *add.tail = *place->stmt;
1678218822Sdim	      *place->stmt = add.head;
1679218822Sdim	    }
1680218822Sdim
1681218822Sdim	  /* Fix the global list pointer if we happened to tack our
1682218822Sdim	     new list at the tail.  */
1683218822Sdim	  if (*old->tail == add.head)
1684218822Sdim	    old->tail = add.tail;
1685218822Sdim
1686218822Sdim	  /* Save the end of this list.  */
1687218822Sdim	  place->stmt = add.tail;
1688218822Sdim
1689218822Sdim	  /* Do the same for the list of output section statements.  */
1690218822Sdim	  newly_added_os = *os_tail;
1691218822Sdim	  *os_tail = NULL;
1692218822Sdim	  newly_added_os->prev = (lang_output_section_statement_type *)
1693218822Sdim	    ((char *) place->os_tail
1694218822Sdim	     - offsetof (lang_output_section_statement_type, next));
1695218822Sdim	  newly_added_os->next = *place->os_tail;
1696218822Sdim	  if (newly_added_os->next != NULL)
1697218822Sdim	    newly_added_os->next->prev = newly_added_os;
1698218822Sdim	  *place->os_tail = newly_added_os;
1699218822Sdim	  place->os_tail = &newly_added_os->next;
1700218822Sdim
1701218822Sdim	  /* Fixing the global list pointer here is a little different.
1702218822Sdim	     We added to the list in lang_enter_output_section_statement,
1703218822Sdim	     trimmed off the new output_section_statment above when
1704218822Sdim	     assigning *os_tail = NULL, but possibly added it back in
1705218822Sdim	     the same place when assigning *place->os_tail.  */
1706218822Sdim	  if (*os_tail == NULL)
1707218822Sdim	    lang_output_section_statement.tail
1708218822Sdim	      = (lang_statement_union_type **) os_tail;
1709218822Sdim	}
1710218822Sdim    }
1711218822Sdim  return os;
171233965Sjdp}
171333965Sjdp
171438889Sjdpstatic void
1715130561Sobrienlang_map_flags (flagword flag)
171638889Sjdp{
171738889Sjdp  if (flag & SEC_ALLOC)
171838889Sjdp    minfo ("a");
171938889Sjdp
172038889Sjdp  if (flag & SEC_CODE)
172138889Sjdp    minfo ("x");
172238889Sjdp
172338889Sjdp  if (flag & SEC_READONLY)
172438889Sjdp    minfo ("r");
172538889Sjdp
172638889Sjdp  if (flag & SEC_DATA)
172738889Sjdp    minfo ("w");
172838889Sjdp
172938889Sjdp  if (flag & SEC_LOAD)
173038889Sjdp    minfo ("l");
173138889Sjdp}
173238889Sjdp
173333965Sjdpvoid
1734130561Sobrienlang_map (void)
173533965Sjdp{
173633965Sjdp  lang_memory_region_type *m;
1737218822Sdim  bfd_boolean dis_header_printed = FALSE;
1738218822Sdim  bfd *p;
173933965Sjdp
1740218822Sdim  LANG_FOR_EACH_INPUT_STATEMENT (file)
1741218822Sdim    {
1742218822Sdim      asection *s;
1743218822Sdim
1744218822Sdim      if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0
1745218822Sdim	  || file->just_syms_flag)
1746218822Sdim	continue;
1747218822Sdim
1748218822Sdim      for (s = file->the_bfd->sections; s != NULL; s = s->next)
1749218822Sdim	if ((s->output_section == NULL
1750218822Sdim	     || s->output_section->owner != output_bfd)
1751218822Sdim	    && (s->flags & (SEC_LINKER_CREATED | SEC_KEEP)) == 0)
1752218822Sdim	  {
1753218822Sdim	    if (! dis_header_printed)
1754218822Sdim	      {
1755218822Sdim		fprintf (config.map_file, _("\nDiscarded input sections\n\n"));
1756218822Sdim		dis_header_printed = TRUE;
1757218822Sdim	      }
1758218822Sdim
1759218822Sdim	    print_input_section (s);
1760218822Sdim	  }
1761218822Sdim    }
1762218822Sdim
176360484Sobrien  minfo (_("\nMemory Configuration\n\n"));
176438889Sjdp  fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
176560484Sobrien	   _("Name"), _("Origin"), _("Length"), _("Attributes"));
176633965Sjdp
1767130561Sobrien  for (m = lang_memory_region_list; m != NULL; m = m->next)
176833965Sjdp    {
176933965Sjdp      char buf[100];
177033965Sjdp      int len;
177133965Sjdp
177233965Sjdp      fprintf (config.map_file, "%-16s ", m->name);
177333965Sjdp
177433965Sjdp      sprintf_vma (buf, m->origin);
177533965Sjdp      minfo ("0x%s ", buf);
177633965Sjdp      len = strlen (buf);
177733965Sjdp      while (len < 16)
177833965Sjdp	{
177933965Sjdp	  print_space ();
178033965Sjdp	  ++len;
178133965Sjdp	}
178233965Sjdp
178338889Sjdp      minfo ("0x%V", m->length);
178438889Sjdp      if (m->flags || m->not_flags)
178538889Sjdp	{
178638889Sjdp#ifndef BFD64
178738889Sjdp	  minfo ("        ");
178838889Sjdp#endif
178938889Sjdp	  if (m->flags)
179038889Sjdp	    {
179138889Sjdp	      print_space ();
179238889Sjdp	      lang_map_flags (m->flags);
179338889Sjdp	    }
179438889Sjdp
179538889Sjdp	  if (m->not_flags)
179638889Sjdp	    {
179738889Sjdp	      minfo (" !");
179838889Sjdp	      lang_map_flags (m->not_flags);
179938889Sjdp	    }
180038889Sjdp	}
180138889Sjdp
180238889Sjdp      print_nl ();
180333965Sjdp    }
180433965Sjdp
180560484Sobrien  fprintf (config.map_file, _("\nLinker script and memory map\n\n"));
180633965Sjdp
1807218822Sdim  if (! link_info.reduce_memory_overheads)
1808218822Sdim    {
1809218822Sdim      obstack_begin (&map_obstack, 1000);
1810218822Sdim      for (p = link_info.input_bfds; p != (bfd *) NULL; p = p->link_next)
1811218822Sdim	bfd_map_over_sections (p, init_map_userdata, 0);
1812218822Sdim      bfd_link_hash_traverse (link_info.hash, sort_def_symbol, 0);
1813218822Sdim    }
181433965Sjdp  print_statements ();
181533965Sjdp}
181633965Sjdp
1817218822Sdimstatic void
1818218822Sdiminit_map_userdata (abfd, sec, data)
1819218822Sdim     bfd *abfd ATTRIBUTE_UNUSED;
1820218822Sdim     asection *sec;
1821218822Sdim     void *data ATTRIBUTE_UNUSED;
1822218822Sdim{
1823218822Sdim  fat_section_userdata_type *new_data
1824218822Sdim    = ((fat_section_userdata_type *) (stat_alloc
1825218822Sdim				      (sizeof (fat_section_userdata_type))));
1826218822Sdim
1827218822Sdim  ASSERT (get_userdata (sec) == NULL);
1828218822Sdim  get_userdata (sec) = new_data;
1829218822Sdim  new_data->map_symbol_def_tail = &new_data->map_symbol_def_head;
1830218822Sdim}
1831218822Sdim
1832218822Sdimstatic bfd_boolean
1833218822Sdimsort_def_symbol (hash_entry, info)
1834218822Sdim     struct bfd_link_hash_entry *hash_entry;
1835218822Sdim     void *info ATTRIBUTE_UNUSED;
1836218822Sdim{
1837218822Sdim  if (hash_entry->type == bfd_link_hash_defined
1838218822Sdim      || hash_entry->type == bfd_link_hash_defweak)
1839218822Sdim    {
1840218822Sdim      struct fat_user_section_struct *ud;
1841218822Sdim      struct map_symbol_def *def;
1842218822Sdim
1843218822Sdim      ud = get_userdata (hash_entry->u.def.section);
1844218822Sdim      if  (! ud)
1845218822Sdim	{
1846218822Sdim	  /* ??? What do we have to do to initialize this beforehand?  */
1847218822Sdim	  /* The first time we get here is bfd_abs_section...  */
1848218822Sdim	  init_map_userdata (0, hash_entry->u.def.section, 0);
1849218822Sdim	  ud = get_userdata (hash_entry->u.def.section);
1850218822Sdim	}
1851218822Sdim      else if  (!ud->map_symbol_def_tail)
1852218822Sdim	ud->map_symbol_def_tail = &ud->map_symbol_def_head;
1853218822Sdim
1854218822Sdim      def = obstack_alloc (&map_obstack, sizeof *def);
1855218822Sdim      def->entry = hash_entry;
1856218822Sdim      *(ud->map_symbol_def_tail) = def;
1857218822Sdim      ud->map_symbol_def_tail = &def->next;
1858218822Sdim    }
1859218822Sdim  return TRUE;
1860218822Sdim}
1861218822Sdim
186233965Sjdp/* Initialize an output section.  */
186333965Sjdp
186433965Sjdpstatic void
1865218822Sdiminit_os (lang_output_section_statement_type *s, asection *isec,
1866218822Sdim	 flagword flags)
186733965Sjdp{
186833965Sjdp  if (s->bfd_section != NULL)
186933965Sjdp    return;
187033965Sjdp
187133965Sjdp  if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
187289857Sobrien    einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
187333965Sjdp
187433965Sjdp  s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
1875130561Sobrien  if (s->bfd_section == NULL)
1876218822Sdim    s->bfd_section = bfd_make_section_with_flags (output_bfd, s->name,
1877218822Sdim						  flags);
1878130561Sobrien  if (s->bfd_section == NULL)
187933965Sjdp    {
188060484Sobrien      einfo (_("%P%F: output format %s cannot represent section called %s\n"),
188133965Sjdp	     output_bfd->xvec->name, s->name);
188233965Sjdp    }
188333965Sjdp  s->bfd_section->output_section = s->bfd_section;
188433965Sjdp  s->bfd_section->output_offset = 0;
188533965Sjdp
1886218822Sdim  if (!link_info.reduce_memory_overheads)
1887218822Sdim    {
1888218822Sdim      fat_section_userdata_type *new
1889218822Sdim	= stat_alloc (sizeof (fat_section_userdata_type));
1890218822Sdim      memset (new, 0, sizeof (fat_section_userdata_type));
1891218822Sdim      get_userdata (s->bfd_section) = new;
1892218822Sdim    }
1893218822Sdim
189433965Sjdp  /* If there is a base address, make sure that any sections it might
189533965Sjdp     mention are initialized.  */
189633965Sjdp  if (s->addr_tree != NULL)
189733965Sjdp    exp_init_os (s->addr_tree);
1898130561Sobrien
1899130561Sobrien  if (s->load_base != NULL)
1900130561Sobrien    exp_init_os (s->load_base);
1901218822Sdim
1902218822Sdim  /* If supplied an alignment, set it.  */
1903218822Sdim  if (s->section_alignment != -1)
1904218822Sdim    s->bfd_section->alignment_power = s->section_alignment;
1905218822Sdim
1906218822Sdim  if (isec)
1907218822Sdim    bfd_init_private_section_data (isec->owner, isec,
1908218822Sdim				   output_bfd, s->bfd_section,
1909218822Sdim				   &link_info);
191033965Sjdp}
191133965Sjdp
191233965Sjdp/* Make sure that all output sections mentioned in an expression are
191333965Sjdp   initialized.  */
191433965Sjdp
191533965Sjdpstatic void
1916130561Sobrienexp_init_os (etree_type *exp)
191733965Sjdp{
191833965Sjdp  switch (exp->type.node_class)
191933965Sjdp    {
192033965Sjdp    case etree_assign:
1921218822Sdim    case etree_provide:
192233965Sjdp      exp_init_os (exp->assign.src);
192333965Sjdp      break;
192433965Sjdp
192533965Sjdp    case etree_binary:
192633965Sjdp      exp_init_os (exp->binary.lhs);
192733965Sjdp      exp_init_os (exp->binary.rhs);
192833965Sjdp      break;
192933965Sjdp
193033965Sjdp    case etree_trinary:
193133965Sjdp      exp_init_os (exp->trinary.cond);
193233965Sjdp      exp_init_os (exp->trinary.lhs);
193333965Sjdp      exp_init_os (exp->trinary.rhs);
193433965Sjdp      break;
193533965Sjdp
1936130561Sobrien    case etree_assert:
1937130561Sobrien      exp_init_os (exp->assert_s.child);
1938130561Sobrien      break;
1939218822Sdim
194033965Sjdp    case etree_unary:
194133965Sjdp      exp_init_os (exp->unary.child);
194233965Sjdp      break;
194333965Sjdp
194433965Sjdp    case etree_name:
194533965Sjdp      switch (exp->type.node_code)
194633965Sjdp	{
194733965Sjdp	case ADDR:
194833965Sjdp	case LOADADDR:
194933965Sjdp	case SIZEOF:
195033965Sjdp	  {
195133965Sjdp	    lang_output_section_statement_type *os;
195233965Sjdp
195333965Sjdp	    os = lang_output_section_find (exp->name.name);
195433965Sjdp	    if (os != NULL && os->bfd_section == NULL)
1955218822Sdim	      init_os (os, NULL, 0);
195633965Sjdp	  }
195733965Sjdp	}
195833965Sjdp      break;
195933965Sjdp
196033965Sjdp    default:
196133965Sjdp      break;
196233965Sjdp    }
196333965Sjdp}
196460484Sobrien
196533965Sjdpstatic void
1966130561Sobriensection_already_linked (bfd *abfd, asection *sec, void *data)
196733965Sjdp{
1968130561Sobrien  lang_input_statement_type *entry = data;
196933965Sjdp
197033965Sjdp  /* If we are only reading symbols from this object, then we want to
197133965Sjdp     discard all sections.  */
197233965Sjdp  if (entry->just_syms_flag)
197333965Sjdp    {
1974218822Sdim      bfd_link_just_syms (abfd, sec, &link_info);
197533965Sjdp      return;
197633965Sjdp    }
197733965Sjdp
1978218822Sdim  if (!(abfd->flags & DYNAMIC))
1979218822Sdim    bfd_section_already_linked (abfd, sec, &link_info);
198033965Sjdp}
198133965Sjdp
198233965Sjdp/* The wild routines.
198333965Sjdp
198433965Sjdp   These expand statements like *(.text) and foo.o to a list of
198533965Sjdp   explicit actions, like foo.o(.text), bar.o(.text) and
198633965Sjdp   foo.o(.text, .data).  */
198733965Sjdp
198833965Sjdp/* Add SECTION to the output section OUTPUT.  Do this by creating a
198933965Sjdp   lang_input_section statement which is placed at PTR.  FILE is the
199033965Sjdp   input file which holds SECTION.  */
199133965Sjdp
199233965Sjdpvoid
1993130561Sobrienlang_add_section (lang_statement_list_type *ptr,
1994130561Sobrien		  asection *section,
1995218822Sdim		  lang_output_section_statement_type *output)
199633965Sjdp{
1997218822Sdim  flagword flags = section->flags;
1998130561Sobrien  bfd_boolean discard;
199933965Sjdp
2000218822Sdim  /* Discard sections marked with SEC_EXCLUDE.  */
2001218822Sdim  discard = (flags & SEC_EXCLUDE) != 0;
200233965Sjdp
200333965Sjdp  /* Discard input sections which are assigned to a section named
200433965Sjdp     DISCARD_SECTION_NAME.  */
200533965Sjdp  if (strcmp (output->name, DISCARD_SECTION_NAME) == 0)
2006130561Sobrien    discard = TRUE;
200733965Sjdp
200833965Sjdp  /* Discard debugging sections if we are stripping debugging
200933965Sjdp     information.  */
201033965Sjdp  if ((link_info.strip == strip_debugger || link_info.strip == strip_all)
201133965Sjdp      && (flags & SEC_DEBUGGING) != 0)
2012130561Sobrien    discard = TRUE;
201333965Sjdp
201433965Sjdp  if (discard)
201533965Sjdp    {
201633965Sjdp      if (section->output_section == NULL)
201733965Sjdp	{
201833965Sjdp	  /* This prevents future calls from assigning this section.  */
201933965Sjdp	  section->output_section = bfd_abs_section_ptr;
202033965Sjdp	}
202133965Sjdp      return;
202233965Sjdp    }
202333965Sjdp
202433965Sjdp  if (section->output_section == NULL)
202533965Sjdp    {
2026130561Sobrien      bfd_boolean first;
202733965Sjdp      lang_input_section_type *new;
202838889Sjdp      flagword flags;
202933965Sjdp
2030218822Sdim      flags = section->flags;
2031218822Sdim
2032218822Sdim      /* We don't copy the SEC_NEVER_LOAD flag from an input section
2033218822Sdim	 to an output section, because we want to be able to include a
2034218822Sdim	 SEC_NEVER_LOAD section in the middle of an otherwise loaded
2035218822Sdim	 section (I don't know why we want to do this, but we do).
2036218822Sdim	 build_link_order in ldwrite.c handles this case by turning
2037218822Sdim	 the embedded SEC_NEVER_LOAD section into a fill.  */
2038218822Sdim
2039218822Sdim      flags &= ~ SEC_NEVER_LOAD;
2040218822Sdim
2041218822Sdim      switch (output->sectype)
2042218822Sdim	{
2043218822Sdim	case normal_section:
2044218822Sdim	case overlay_section:
2045218822Sdim	  break;
2046218822Sdim	case noalloc_section:
2047218822Sdim	  flags &= ~SEC_ALLOC;
2048218822Sdim	  break;
2049218822Sdim	case noload_section:
2050218822Sdim	  flags &= ~SEC_LOAD;
2051218822Sdim	  flags |= SEC_NEVER_LOAD;
2052218822Sdim	  break;
2053218822Sdim	}
2054218822Sdim
205533965Sjdp      if (output->bfd_section == NULL)
2056218822Sdim	init_os (output, section, flags);
205733965Sjdp
205878828Sobrien      first = ! output->bfd_section->linker_has_input;
205978828Sobrien      output->bfd_section->linker_has_input = 1;
206078828Sobrien
2061218822Sdim      if (!link_info.relocatable
2062218822Sdim	  && !stripped_excluded_sections)
2063218822Sdim	{
2064218822Sdim	  asection *s = output->bfd_section->map_tail.s;
2065218822Sdim	  output->bfd_section->map_tail.s = section;
2066218822Sdim	  section->map_head.s = NULL;
2067218822Sdim	  section->map_tail.s = s;
2068218822Sdim	  if (s != NULL)
2069218822Sdim	    s->map_head.s = section;
2070218822Sdim	  else
2071218822Sdim	    output->bfd_section->map_head.s = section;
2072218822Sdim	}
2073218822Sdim
207477298Sobrien      /* Add a section reference to the list.  */
207533965Sjdp      new = new_stat (lang_input_section, ptr);
207633965Sjdp
207733965Sjdp      new->section = section;
207833965Sjdp      section->output_section = output->bfd_section;
207933965Sjdp
208038889Sjdp      /* If final link, don't copy the SEC_LINK_ONCE flags, they've
208138889Sjdp	 already been processed.  One reason to do this is that on pe
208238889Sjdp	 format targets, .text$foo sections go into .text and it's odd
208338889Sjdp	 to see .text with SEC_LINK_ONCE set.  */
208433965Sjdp
2085130561Sobrien      if (! link_info.relocatable)
208638889Sjdp	flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES);
208738889Sjdp
208838889Sjdp      /* If this is not the first input section, and the SEC_READONLY
2089218822Sdim	 flag is not currently set, then don't set it just because the
2090218822Sdim	 input section has it set.  */
209138889Sjdp
2092218822Sdim      if (! first && (output->bfd_section->flags & SEC_READONLY) == 0)
209338889Sjdp	flags &= ~ SEC_READONLY;
209438889Sjdp
209589857Sobrien      /* Keep SEC_MERGE and SEC_STRINGS only if they are the same.  */
209689857Sobrien      if (! first
2097218822Sdim	  && ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS))
209889857Sobrien	      != (flags & (SEC_MERGE | SEC_STRINGS))
209989857Sobrien	      || ((flags & SEC_MERGE)
2100218822Sdim		  && output->bfd_section->entsize != section->entsize)))
210189857Sobrien	{
2102218822Sdim	  output->bfd_section->flags &= ~ (SEC_MERGE | SEC_STRINGS);
210389857Sobrien	  flags &= ~ (SEC_MERGE | SEC_STRINGS);
210489857Sobrien	}
210589857Sobrien
2106218822Sdim      output->bfd_section->flags |= flags;
210738889Sjdp
210889857Sobrien      if (flags & SEC_MERGE)
2109218822Sdim	output->bfd_section->entsize = section->entsize;
211089857Sobrien
211138889Sjdp      /* If SEC_READONLY is not set in the input section, then clear
2112218822Sdim	 it from the output section.  */
211338889Sjdp      if ((section->flags & SEC_READONLY) == 0)
2114218822Sdim	output->bfd_section->flags &= ~SEC_READONLY;
211538889Sjdp
211660484Sobrien      /* Copy over SEC_SMALL_DATA.  */
211760484Sobrien      if (section->flags & SEC_SMALL_DATA)
2118218822Sdim	output->bfd_section->flags |= SEC_SMALL_DATA;
211960484Sobrien
212033965Sjdp      if (section->alignment_power > output->bfd_section->alignment_power)
212133965Sjdp	output->bfd_section->alignment_power = section->alignment_power;
212233965Sjdp
2123218822Sdim      if (bfd_get_arch (section->owner) == bfd_arch_tic54x
2124218822Sdim	  && (section->flags & SEC_TIC54X_BLOCK) != 0)
212577298Sobrien	{
2126218822Sdim	  output->bfd_section->flags |= SEC_TIC54X_BLOCK;
212777298Sobrien	  /* FIXME: This value should really be obtained from the bfd...  */
212877298Sobrien	  output->block_value = 128;
212977298Sobrien	}
213033965Sjdp    }
213133965Sjdp}
213233965Sjdp
213360484Sobrien/* Handle wildcard sorting.  This returns the lang_input_section which
213460484Sobrien   should follow the one we are going to create for SECTION and FILE,
213560484Sobrien   based on the sorting requirements of WILD.  It returns NULL if the
213660484Sobrien   new section should just go at the end of the current list.  */
213733965Sjdp
213860484Sobrienstatic lang_statement_union_type *
2139130561Sobrienwild_sort (lang_wild_statement_type *wild,
2140130561Sobrien	   struct wildcard_list *sec,
2141130561Sobrien	   lang_input_statement_type *file,
2142130561Sobrien	   asection *section)
214333965Sjdp{
214460484Sobrien  const char *section_name;
214560484Sobrien  lang_statement_union_type *l;
214660484Sobrien
2147218822Sdim  if (!wild->filenames_sorted
2148218822Sdim      && (sec == NULL || sec->spec.sorted == none))
214960484Sobrien    return NULL;
215060484Sobrien
215160484Sobrien  section_name = bfd_get_section_name (file->the_bfd, section);
215289857Sobrien  for (l = wild->children.head; l != NULL; l = l->header.next)
215333965Sjdp    {
215460484Sobrien      lang_input_section_type *ls;
215533965Sjdp
215660484Sobrien      if (l->header.type != lang_input_section_enum)
215760484Sobrien	continue;
215860484Sobrien      ls = &l->input_section;
215933965Sjdp
216060484Sobrien      /* Sorting by filename takes precedence over sorting by section
2161218822Sdim	 name.  */
216260484Sobrien
216360484Sobrien      if (wild->filenames_sorted)
216433965Sjdp	{
216560484Sobrien	  const char *fn, *ln;
2166130561Sobrien	  bfd_boolean fa, la;
216760484Sobrien	  int i;
216833965Sjdp
216960484Sobrien	  /* The PE support for the .idata section as generated by
2170218822Sdim	     dlltool assumes that files will be sorted by the name of
2171218822Sdim	     the archive and then the name of the file within the
2172218822Sdim	     archive.  */
217333965Sjdp
217460484Sobrien	  if (file->the_bfd != NULL
217560484Sobrien	      && bfd_my_archive (file->the_bfd) != NULL)
217660484Sobrien	    {
217760484Sobrien	      fn = bfd_get_filename (bfd_my_archive (file->the_bfd));
2178130561Sobrien	      fa = TRUE;
217960484Sobrien	    }
218060484Sobrien	  else
218160484Sobrien	    {
218260484Sobrien	      fn = file->filename;
2183130561Sobrien	      fa = FALSE;
218460484Sobrien	    }
218533965Sjdp
2186218822Sdim	  if (bfd_my_archive (ls->section->owner) != NULL)
218760484Sobrien	    {
2188218822Sdim	      ln = bfd_get_filename (bfd_my_archive (ls->section->owner));
2189130561Sobrien	      la = TRUE;
219060484Sobrien	    }
219133965Sjdp	  else
219233965Sjdp	    {
2193218822Sdim	      ln = ls->section->owner->filename;
2194130561Sobrien	      la = FALSE;
219560484Sobrien	    }
219633965Sjdp
219760484Sobrien	  i = strcmp (fn, ln);
219860484Sobrien	  if (i > 0)
219960484Sobrien	    continue;
220060484Sobrien	  else if (i < 0)
220160484Sobrien	    break;
220260484Sobrien
220360484Sobrien	  if (fa || la)
220460484Sobrien	    {
220560484Sobrien	      if (fa)
220660484Sobrien		fn = file->filename;
220760484Sobrien	      if (la)
2208218822Sdim		ln = ls->section->owner->filename;
220960484Sobrien
221060484Sobrien	      i = strcmp (fn, ln);
221160484Sobrien	      if (i > 0)
221260484Sobrien		continue;
221360484Sobrien	      else if (i < 0)
221460484Sobrien		break;
221533965Sjdp	    }
221633965Sjdp	}
221760484Sobrien
221860484Sobrien      /* Here either the files are not sorted by name, or we are
2219218822Sdim	 looking at the sections for this file.  */
222060484Sobrien
2221218822Sdim      if (sec != NULL && sec->spec.sorted != none)
2222218822Sdim	if (compare_section (sec->spec.sorted, section, ls->section) < 0)
2223218822Sdim	  break;
222433965Sjdp    }
222560484Sobrien
222660484Sobrien  return l;
222733965Sjdp}
222833965Sjdp
222960484Sobrien/* Expand a wild statement for a particular FILE.  SECTION may be
223060484Sobrien   NULL, in which case it is a wild card.  */
223160484Sobrien
223260484Sobrienstatic void
2233130561Sobrienoutput_section_callback (lang_wild_statement_type *ptr,
2234130561Sobrien			 struct wildcard_list *sec,
2235130561Sobrien			 asection *section,
2236130561Sobrien			 lang_input_statement_type *file,
2237130561Sobrien			 void *output)
223860484Sobrien{
223960484Sobrien  lang_statement_union_type *before;
224077298Sobrien
224189857Sobrien  /* Exclude sections that match UNIQUE_SECTION_LIST.  */
2242218822Sdim  if (unique_section_p (section))
224389857Sobrien    return;
224489857Sobrien
224589857Sobrien  before = wild_sort (ptr, sec, file, section);
224677298Sobrien
224760484Sobrien  /* Here BEFORE points to the lang_input_section which
224860484Sobrien     should follow the one we are about to add.  If BEFORE
224960484Sobrien     is NULL, then the section should just go at the end
225060484Sobrien     of the current list.  */
225177298Sobrien
225260484Sobrien  if (before == NULL)
225389857Sobrien    lang_add_section (&ptr->children, section,
2254218822Sdim		      (lang_output_section_statement_type *) output);
225560484Sobrien  else
225660484Sobrien    {
225760484Sobrien      lang_statement_list_type list;
225860484Sobrien      lang_statement_union_type **pp;
225977298Sobrien
226060484Sobrien      lang_list_init (&list);
226189857Sobrien      lang_add_section (&list, section,
2262218822Sdim			(lang_output_section_statement_type *) output);
226377298Sobrien
226460484Sobrien      /* If we are discarding the section, LIST.HEAD will
226560484Sobrien	 be NULL.  */
226660484Sobrien      if (list.head != NULL)
226760484Sobrien	{
226889857Sobrien	  ASSERT (list.head->header.next == NULL);
226977298Sobrien
227060484Sobrien	  for (pp = &ptr->children.head;
227160484Sobrien	       *pp != before;
227289857Sobrien	       pp = &(*pp)->header.next)
227360484Sobrien	    ASSERT (*pp != NULL);
227477298Sobrien
227589857Sobrien	  list.head->header.next = *pp;
227660484Sobrien	  *pp = list.head;
227760484Sobrien	}
227860484Sobrien    }
227960484Sobrien}
228060484Sobrien
2281218822Sdim/* Check if all sections in a wild statement for a particular FILE
2282218822Sdim   are readonly.  */
2283218822Sdim
2284218822Sdimstatic void
2285218822Sdimcheck_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED,
2286218822Sdim			struct wildcard_list *sec ATTRIBUTE_UNUSED,
2287218822Sdim			asection *section,
2288218822Sdim			lang_input_statement_type *file ATTRIBUTE_UNUSED,
2289218822Sdim			void *data)
2290218822Sdim{
2291218822Sdim  /* Exclude sections that match UNIQUE_SECTION_LIST.  */
2292218822Sdim  if (unique_section_p (section))
2293218822Sdim    return;
2294218822Sdim
2295218822Sdim  if (section->output_section == NULL && (section->flags & SEC_READONLY) == 0)
2296218822Sdim    ((lang_output_section_statement_type *) data)->all_input_readonly = FALSE;
2297218822Sdim}
2298218822Sdim
229933965Sjdp/* This is passed a file name which must have been seen already and
230033965Sjdp   added to the statement tree.  We will see if it has been opened
230133965Sjdp   already and had its symbols read.  If not then we'll read it.  */
230233965Sjdp
230333965Sjdpstatic lang_input_statement_type *
2304130561Sobrienlookup_name (const char *name)
230533965Sjdp{
230633965Sjdp  lang_input_statement_type *search;
230733965Sjdp
230833965Sjdp  for (search = (lang_input_statement_type *) input_file_chain.head;
2309130561Sobrien       search != NULL;
231033965Sjdp       search = (lang_input_statement_type *) search->next_real_file)
231133965Sjdp    {
2312130561Sobrien      /* Use the local_sym_name as the name of the file that has
2313130561Sobrien	 already been loaded as filename might have been transformed
2314130561Sobrien	 via the search directory lookup mechanism.  */
2315218822Sdim      const char *filename = search->local_sym_name;
2316130561Sobrien
2317130561Sobrien      if (filename != NULL
2318130561Sobrien	  && strcmp (filename, name) == 0)
231933965Sjdp	break;
232033965Sjdp    }
232133965Sjdp
2322130561Sobrien  if (search == NULL)
2323218822Sdim    search = new_afile (name, lang_input_file_is_search_file_enum,
2324218822Sdim			default_target, FALSE);
232533965Sjdp
232633965Sjdp  /* If we have already added this file, or this file is not real
2327218822Sdim     don't add this file.  */
2328218822Sdim  if (search->loaded || !search->real)
232933965Sjdp    return search;
233033965Sjdp
2331130561Sobrien  if (! load_symbols (search, NULL))
233289857Sobrien    return NULL;
233333965Sjdp
233433965Sjdp  return search;
233533965Sjdp}
233633965Sjdp
2337218822Sdim/* Save LIST as a list of libraries whose symbols should not be exported.  */
2338218822Sdim
2339218822Sdimstruct excluded_lib
2340218822Sdim{
2341218822Sdim  char *name;
2342218822Sdim  struct excluded_lib *next;
2343218822Sdim};
2344218822Sdimstatic struct excluded_lib *excluded_libs;
2345218822Sdim
2346218822Sdimvoid
2347218822Sdimadd_excluded_libs (const char *list)
2348218822Sdim{
2349218822Sdim  const char *p = list, *end;
2350218822Sdim
2351218822Sdim  while (*p != '\0')
2352218822Sdim    {
2353218822Sdim      struct excluded_lib *entry;
2354218822Sdim      end = strpbrk (p, ",:");
2355218822Sdim      if (end == NULL)
2356218822Sdim	end = p + strlen (p);
2357218822Sdim      entry = xmalloc (sizeof (*entry));
2358218822Sdim      entry->next = excluded_libs;
2359218822Sdim      entry->name = xmalloc (end - p + 1);
2360218822Sdim      memcpy (entry->name, p, end - p);
2361218822Sdim      entry->name[end - p] = '\0';
2362218822Sdim      excluded_libs = entry;
2363218822Sdim      if (*end == '\0')
2364218822Sdim	break;
2365218822Sdim      p = end + 1;
2366218822Sdim    }
2367218822Sdim}
2368218822Sdim
2369218822Sdimstatic void
2370218822Sdimcheck_excluded_libs (bfd *abfd)
2371218822Sdim{
2372218822Sdim  struct excluded_lib *lib = excluded_libs;
2373218822Sdim
2374218822Sdim  while (lib)
2375218822Sdim    {
2376218822Sdim      int len = strlen (lib->name);
2377218822Sdim      const char *filename = lbasename (abfd->filename);
2378218822Sdim
2379218822Sdim      if (strcmp (lib->name, "ALL") == 0)
2380218822Sdim	{
2381218822Sdim	  abfd->no_export = TRUE;
2382218822Sdim	  return;
2383218822Sdim	}
2384218822Sdim
2385218822Sdim      if (strncmp (lib->name, filename, len) == 0
2386218822Sdim	  && (filename[len] == '\0'
2387218822Sdim	      || (filename[len] == '.' && filename[len + 1] == 'a'
2388218822Sdim		  && filename[len + 2] == '\0')))
2389218822Sdim	{
2390218822Sdim	  abfd->no_export = TRUE;
2391218822Sdim	  return;
2392218822Sdim	}
2393218822Sdim
2394218822Sdim      lib = lib->next;
2395218822Sdim    }
2396218822Sdim}
2397218822Sdim
239833965Sjdp/* Get the symbols for an input file.  */
239933965Sjdp
2400218822Sdimbfd_boolean
2401130561Sobrienload_symbols (lang_input_statement_type *entry,
2402130561Sobrien	      lang_statement_list_type *place)
240333965Sjdp{
240433965Sjdp  char **matching;
240533965Sjdp
240633965Sjdp  if (entry->loaded)
2407130561Sobrien    return TRUE;
240833965Sjdp
240933965Sjdp  ldfile_open_file (entry);
241033965Sjdp
241133965Sjdp  if (! bfd_check_format (entry->the_bfd, bfd_archive)
241233965Sjdp      && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
241333965Sjdp    {
241433965Sjdp      bfd_error_type err;
241533965Sjdp      lang_statement_list_type *hold;
2416130561Sobrien      bfd_boolean bad_load = TRUE;
2417130561Sobrien      bfd_boolean save_ldlang_sysrooted_script;
2418218822Sdim      bfd_boolean save_as_needed, save_add_needed;
2419104834Sobrien
242033965Sjdp      err = bfd_get_error ();
242178828Sobrien
242278828Sobrien      /* See if the emulation has some special knowledge.  */
242378828Sobrien      if (ldemul_unrecognized_file (entry))
2424130561Sobrien	return TRUE;
242578828Sobrien
242633965Sjdp      if (err == bfd_error_file_ambiguously_recognized)
242733965Sjdp	{
242833965Sjdp	  char **p;
242933965Sjdp
243060484Sobrien	  einfo (_("%B: file not recognized: %E\n"), entry->the_bfd);
243160484Sobrien	  einfo (_("%B: matching formats:"), entry->the_bfd);
243233965Sjdp	  for (p = matching; *p != NULL; p++)
243333965Sjdp	    einfo (" %s", *p);
243433965Sjdp	  einfo ("%F\n");
243533965Sjdp	}
243633965Sjdp      else if (err != bfd_error_file_not_recognized
243733965Sjdp	       || place == NULL)
243889857Sobrien	  einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
243989857Sobrien      else
2440130561Sobrien	bad_load = FALSE;
2441104834Sobrien
244233965Sjdp      bfd_close (entry->the_bfd);
244333965Sjdp      entry->the_bfd = NULL;
244433965Sjdp
244533965Sjdp      /* Try to interpret the file as a linker script.  */
244633965Sjdp      ldfile_open_command_file (entry->filename);
244733965Sjdp
244833965Sjdp      hold = stat_ptr;
244933965Sjdp      stat_ptr = place;
2450130561Sobrien      save_ldlang_sysrooted_script = ldlang_sysrooted_script;
2451130561Sobrien      ldlang_sysrooted_script = entry->sysrooted;
2452218822Sdim      save_as_needed = as_needed;
2453218822Sdim      as_needed = entry->as_needed;
2454218822Sdim      save_add_needed = add_needed;
2455218822Sdim      add_needed = entry->add_needed;
245633965Sjdp
2457130561Sobrien      ldfile_assumed_script = TRUE;
245833965Sjdp      parser_input = input_script;
2459218822Sdim      /* We want to use the same -Bdynamic/-Bstatic as the one for
2460218822Sdim	 ENTRY.  */
2461218822Sdim      config.dynamic_link = entry->dynamic;
246233965Sjdp      yyparse ();
2463130561Sobrien      ldfile_assumed_script = FALSE;
246433965Sjdp
2465130561Sobrien      ldlang_sysrooted_script = save_ldlang_sysrooted_script;
2466218822Sdim      as_needed = save_as_needed;
2467218822Sdim      add_needed = save_add_needed;
246833965Sjdp      stat_ptr = hold;
246933965Sjdp
247089857Sobrien      return ! bad_load;
247133965Sjdp    }
247233965Sjdp
247360484Sobrien  if (ldemul_recognized_file (entry))
2474130561Sobrien    return TRUE;
247560484Sobrien
247633965Sjdp  /* We don't call ldlang_add_file for an archive.  Instead, the
247733965Sjdp     add_symbols entry point will call ldlang_add_file, via the
247833965Sjdp     add_archive_element callback, for each element of the archive
247933965Sjdp     which is used.  */
248033965Sjdp  switch (bfd_get_format (entry->the_bfd))
248133965Sjdp    {
248233965Sjdp    default:
248333965Sjdp      break;
248433965Sjdp
248533965Sjdp    case bfd_object:
248633965Sjdp      ldlang_add_file (entry);
248733965Sjdp      if (trace_files || trace_file_tries)
248833965Sjdp	info_msg ("%I\n", entry);
248933965Sjdp      break;
249033965Sjdp
249133965Sjdp    case bfd_archive:
2492218822Sdim      check_excluded_libs (entry->the_bfd);
2493218822Sdim
249433965Sjdp      if (entry->whole_archive)
249533965Sjdp	{
2496104834Sobrien	  bfd *member = NULL;
2497130561Sobrien	  bfd_boolean loaded = TRUE;
249889857Sobrien
249989857Sobrien	  for (;;)
250033965Sjdp	    {
250189857Sobrien	      member = bfd_openr_next_archived_file (entry->the_bfd, member);
250289857Sobrien
250389857Sobrien	      if (member == NULL)
250489857Sobrien		break;
2505104834Sobrien
250633965Sjdp	      if (! bfd_check_format (member, bfd_object))
250789857Sobrien		{
250889857Sobrien		  einfo (_("%F%B: member %B in archive is not an object\n"),
250989857Sobrien			 entry->the_bfd, member);
2510130561Sobrien		  loaded = FALSE;
251189857Sobrien		}
251289857Sobrien
251333965Sjdp	      if (! ((*link_info.callbacks->add_archive_element)
251433965Sjdp		     (&link_info, member, "--whole-archive")))
251533965Sjdp		abort ();
251689857Sobrien
251733965Sjdp	      if (! bfd_link_add_symbols (member, &link_info))
251889857Sobrien		{
251989857Sobrien		  einfo (_("%F%B: could not read symbols: %E\n"), member);
2520130561Sobrien		  loaded = FALSE;
252189857Sobrien		}
252233965Sjdp	    }
252333965Sjdp
252489857Sobrien	  entry->loaded = loaded;
252589857Sobrien	  return loaded;
252633965Sjdp	}
252789857Sobrien      break;
252833965Sjdp    }
252933965Sjdp
253089857Sobrien  if (bfd_link_add_symbols (entry->the_bfd, &link_info))
2531130561Sobrien    entry->loaded = TRUE;
253289857Sobrien  else
253360484Sobrien    einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd);
253433965Sjdp
253589857Sobrien  return entry->loaded;
253633965Sjdp}
253733965Sjdp
253889857Sobrien/* Handle a wild statement.  S->FILENAME or S->SECTION_LIST or both
253989857Sobrien   may be NULL, indicating that it is a wildcard.  Separate
254089857Sobrien   lang_input_section statements are created for each part of the
254189857Sobrien   expansion; they are added after the wild statement S.  OUTPUT is
254289857Sobrien   the output section.  */
254333965Sjdp
254433965Sjdpstatic void
2545130561Sobrienwild (lang_wild_statement_type *s,
2546130561Sobrien      const char *target ATTRIBUTE_UNUSED,
2547130561Sobrien      lang_output_section_statement_type *output)
254833965Sjdp{
254989857Sobrien  struct wildcard_list *sec;
255033965Sjdp
2551218822Sdim  if (s->handler_data[0]
2552218822Sdim      && s->handler_data[0]->spec.sorted == by_name
2553218822Sdim      && !s->filenames_sorted)
2554218822Sdim    {
2555218822Sdim      lang_section_bst_type *tree;
255689857Sobrien
2557218822Sdim      walk_wild (s, output_section_callback_fast, output);
2558218822Sdim
2559218822Sdim      tree = s->tree;
2560218822Sdim      if (tree)
2561218822Sdim	{
2562218822Sdim	  output_section_callback_tree_to_list (s, tree, output);
2563218822Sdim	  s->tree = NULL;
2564218822Sdim	}
2565218822Sdim    }
2566218822Sdim  else
2567218822Sdim    walk_wild (s, output_section_callback, output);
2568218822Sdim
2569218822Sdim  if (default_common_section == NULL)
2570218822Sdim    for (sec = s->section_list; sec != NULL; sec = sec->next)
257189857Sobrien      if (sec->spec.name != NULL && strcmp (sec->spec.name, "COMMON") == 0)
257289857Sobrien	{
257389857Sobrien	  /* Remember the section that common is going to in case we
2574104834Sobrien	     later get something which doesn't know where to put it.  */
257589857Sobrien	  default_common_section = output;
2576218822Sdim	  break;
257789857Sobrien	}
257860484Sobrien}
257960484Sobrien
2580130561Sobrien/* Return TRUE iff target is the sought target.  */
258177298Sobrien
258260484Sobrienstatic int
2583130561Sobrienget_target (const bfd_target *target, void *data)
258460484Sobrien{
2585130561Sobrien  const char *sought = data;
258677298Sobrien
258760484Sobrien  return strcmp (target->name, sought) == 0;
258860484Sobrien}
258960484Sobrien
259060484Sobrien/* Like strcpy() but convert to lower case as well.  */
259177298Sobrien
259260484Sobrienstatic void
2593130561Sobrienstricpy (char *dest, char *src)
259460484Sobrien{
259560484Sobrien  char c;
259677298Sobrien
259777298Sobrien  while ((c = *src++) != 0)
259889857Sobrien    *dest++ = TOLOWER (c);
259960484Sobrien
260077298Sobrien  *dest = 0;
260160484Sobrien}
260260484Sobrien
2603130561Sobrien/* Remove the first occurrence of needle (if any) in haystack
260460484Sobrien   from haystack.  */
260577298Sobrien
260660484Sobrienstatic void
2607130561Sobrienstrcut (char *haystack, char *needle)
260860484Sobrien{
260960484Sobrien  haystack = strstr (haystack, needle);
261077298Sobrien
261160484Sobrien  if (haystack)
261233965Sjdp    {
261377298Sobrien      char *src;
261460484Sobrien
261577298Sobrien      for (src = haystack + strlen (needle); *src;)
261677298Sobrien	*haystack++ = *src++;
261777298Sobrien
261877298Sobrien      *haystack = 0;
261933965Sjdp    }
262060484Sobrien}
262133965Sjdp
262260484Sobrien/* Compare two target format name strings.
262360484Sobrien   Return a value indicating how "similar" they are.  */
262477298Sobrien
262560484Sobrienstatic int
2626130561Sobrienname_compare (char *first, char *second)
262760484Sobrien{
262877298Sobrien  char *copy1;
262977298Sobrien  char *copy2;
263077298Sobrien  int result;
263177298Sobrien
263260484Sobrien  copy1 = xmalloc (strlen (first) + 1);
263360484Sobrien  copy2 = xmalloc (strlen (second) + 1);
263460484Sobrien
263560484Sobrien  /* Convert the names to lower case.  */
263660484Sobrien  stricpy (copy1, first);
263760484Sobrien  stricpy (copy2, second);
263860484Sobrien
2639130561Sobrien  /* Remove size and endian strings from the name.  */
264060484Sobrien  strcut (copy1, "big");
264160484Sobrien  strcut (copy1, "little");
264260484Sobrien  strcut (copy2, "big");
264360484Sobrien  strcut (copy2, "little");
264460484Sobrien
264560484Sobrien  /* Return a value based on how many characters match,
264660484Sobrien     starting from the beginning.   If both strings are
264760484Sobrien     the same then return 10 * their length.  */
264877298Sobrien  for (result = 0; copy1[result] == copy2[result]; result++)
264977298Sobrien    if (copy1[result] == 0)
265060484Sobrien      {
265160484Sobrien	result *= 10;
265260484Sobrien	break;
265360484Sobrien      }
265477298Sobrien
265560484Sobrien  free (copy1);
265660484Sobrien  free (copy2);
265760484Sobrien
265860484Sobrien  return result;
265960484Sobrien}
266060484Sobrien
266160484Sobrien/* Set by closest_target_match() below.  */
266277298Sobrienstatic const bfd_target *winner;
266360484Sobrien
266460484Sobrien/* Scan all the valid bfd targets looking for one that has the endianness
266560484Sobrien   requirement that was specified on the command line, and is the nearest
266660484Sobrien   match to the original output target.  */
266777298Sobrien
266860484Sobrienstatic int
2669130561Sobrienclosest_target_match (const bfd_target *target, void *data)
267060484Sobrien{
2671130561Sobrien  const bfd_target *original = data;
267277298Sobrien
267377298Sobrien  if (command_line.endian == ENDIAN_BIG
267477298Sobrien      && target->byteorder != BFD_ENDIAN_BIG)
267560484Sobrien    return 0;
267677298Sobrien
267777298Sobrien  if (command_line.endian == ENDIAN_LITTLE
267877298Sobrien      && target->byteorder != BFD_ENDIAN_LITTLE)
267960484Sobrien    return 0;
268060484Sobrien
268160484Sobrien  /* Must be the same flavour.  */
268260484Sobrien  if (target->flavour != original->flavour)
268360484Sobrien    return 0;
268460484Sobrien
268560484Sobrien  /* If we have not found a potential winner yet, then record this one.  */
268660484Sobrien  if (winner == NULL)
268733965Sjdp    {
268860484Sobrien      winner = target;
268960484Sobrien      return 0;
269033965Sjdp    }
269160484Sobrien
269260484Sobrien  /* Oh dear, we now have two potential candidates for a successful match.
269377298Sobrien     Compare their names and choose the better one.  */
269478828Sobrien  if (name_compare (target->name, original->name)
269578828Sobrien      > name_compare (winner->name, original->name))
269660484Sobrien    winner = target;
269760484Sobrien
269860484Sobrien  /* Keep on searching until wqe have checked them all.  */
269960484Sobrien  return 0;
270033965Sjdp}
270133965Sjdp
270260484Sobrien/* Return the BFD target format of the first input file.  */
270377298Sobrien
270460484Sobrienstatic char *
2705130561Sobrienget_first_input_target (void)
270660484Sobrien{
270777298Sobrien  char *target = NULL;
270860484Sobrien
270960484Sobrien  LANG_FOR_EACH_INPUT_STATEMENT (s)
271060484Sobrien    {
271160484Sobrien      if (s->header.type == lang_input_statement_enum
271260484Sobrien	  && s->real)
271360484Sobrien	{
271460484Sobrien	  ldfile_open_file (s);
271577298Sobrien
271660484Sobrien	  if (s->the_bfd != NULL
271760484Sobrien	      && bfd_check_format (s->the_bfd, bfd_object))
271860484Sobrien	    {
271960484Sobrien	      target = bfd_get_target (s->the_bfd);
272077298Sobrien
272160484Sobrien	      if (target != NULL)
272260484Sobrien		break;
272360484Sobrien	    }
272460484Sobrien	}
272560484Sobrien    }
272677298Sobrien
272760484Sobrien  return target;
272860484Sobrien}
272960484Sobrien
2730107492Sobrienconst char *
2731130561Sobrienlang_get_output_target (void)
2732107492Sobrien{
2733107492Sobrien  const char *target;
2734107492Sobrien
2735107492Sobrien  /* Has the user told us which output format to use?  */
2736130561Sobrien  if (output_target != NULL)
2737107492Sobrien    return output_target;
2738107492Sobrien
2739107492Sobrien  /* No - has the current target been set to something other than
2740107492Sobrien     the default?  */
2741107492Sobrien  if (current_target != default_target)
2742107492Sobrien    return current_target;
2743107492Sobrien
2744107492Sobrien  /* No - can we determine the format of the first input file?  */
2745107492Sobrien  target = get_first_input_target ();
2746107492Sobrien  if (target != NULL)
2747107492Sobrien    return target;
2748107492Sobrien
2749107492Sobrien  /* Failed - use the default output target.  */
2750107492Sobrien  return default_target;
2751107492Sobrien}
2752107492Sobrien
275333965Sjdp/* Open the output file.  */
275433965Sjdp
275533965Sjdpstatic bfd *
2756130561Sobrienopen_output (const char *name)
275733965Sjdp{
275877298Sobrien  bfd *output;
275933965Sjdp
2760107492Sobrien  output_target = lang_get_output_target ();
276160484Sobrien
276277298Sobrien  /* Has the user requested a particular endianness on the command
276377298Sobrien     line?  */
276460484Sobrien  if (command_line.endian != ENDIAN_UNSET)
276560484Sobrien    {
276677298Sobrien      const bfd_target *target;
276760484Sobrien      enum bfd_endian desired_endian;
276860484Sobrien
276960484Sobrien      /* Get the chosen target.  */
2770130561Sobrien      target = bfd_search_for_target (get_target, (void *) output_target);
277160484Sobrien
277277298Sobrien      /* If the target is not supported, we cannot do anything.  */
277377298Sobrien      if (target != NULL)
277460484Sobrien	{
277577298Sobrien	  if (command_line.endian == ENDIAN_BIG)
277677298Sobrien	    desired_endian = BFD_ENDIAN_BIG;
277760484Sobrien	  else
277877298Sobrien	    desired_endian = BFD_ENDIAN_LITTLE;
277977298Sobrien
278077298Sobrien	  /* See if the target has the wrong endianness.  This should
278177298Sobrien	     not happen if the linker script has provided big and
278277298Sobrien	     little endian alternatives, but some scrips don't do
278377298Sobrien	     this.  */
278477298Sobrien	  if (target->byteorder != desired_endian)
278560484Sobrien	    {
278677298Sobrien	      /* If it does, then see if the target provides
278777298Sobrien		 an alternative with the correct endianness.  */
278877298Sobrien	      if (target->alternative_target != NULL
278977298Sobrien		  && (target->alternative_target->byteorder == desired_endian))
279077298Sobrien		output_target = target->alternative_target->name;
279160484Sobrien	      else
279277298Sobrien		{
279377298Sobrien		  /* Try to find a target as similar as possible to
279477298Sobrien		     the default target, but which has the desired
279577298Sobrien		     endian characteristic.  */
2796130561Sobrien		  bfd_search_for_target (closest_target_match,
2797130561Sobrien					 (void *) target);
279877298Sobrien
279977298Sobrien		  /* Oh dear - we could not find any targets that
280077298Sobrien		     satisfy our requirements.  */
280177298Sobrien		  if (winner == NULL)
2802218822Sdim		    einfo (_("%P: warning: could not find any targets"
2803218822Sdim			     " that match endianness requirement\n"));
280477298Sobrien		  else
280577298Sobrien		    output_target = winner->name;
280677298Sobrien		}
280760484Sobrien	    }
280860484Sobrien	}
280960484Sobrien    }
281077298Sobrien
281133965Sjdp  output = bfd_openw (name, output_target);
281233965Sjdp
2813130561Sobrien  if (output == NULL)
281433965Sjdp    {
281533965Sjdp      if (bfd_get_error () == bfd_error_invalid_target)
281660484Sobrien	einfo (_("%P%F: target %s not found\n"), output_target);
281760484Sobrien
281860484Sobrien      einfo (_("%P%F: cannot open output file %s: %E\n"), name);
281933965Sjdp    }
282033965Sjdp
2821130561Sobrien  delete_output_file_on_failure = TRUE;
282233965Sjdp
282333965Sjdp  if (! bfd_set_format (output, bfd_object))
282460484Sobrien    einfo (_("%P%F:%s: can not make object file: %E\n"), name);
282533965Sjdp  if (! bfd_set_arch_mach (output,
282633965Sjdp			   ldfile_output_architecture,
282733965Sjdp			   ldfile_output_machine))
282860484Sobrien    einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
282933965Sjdp
283033965Sjdp  link_info.hash = bfd_link_hash_table_create (output);
2831130561Sobrien  if (link_info.hash == NULL)
2832218822Sdim    einfo (_("%P%F: can not create hash table: %E\n"));
283333965Sjdp
283433965Sjdp  bfd_set_gp_size (output, g_switch_value);
283533965Sjdp  return output;
283633965Sjdp}
283733965Sjdp
283833965Sjdpstatic void
2839130561Sobrienldlang_open_output (lang_statement_union_type *statement)
284033965Sjdp{
284133965Sjdp  switch (statement->header.type)
284233965Sjdp    {
284333965Sjdp    case lang_output_statement_enum:
2844130561Sobrien      ASSERT (output_bfd == NULL);
284533965Sjdp      output_bfd = open_output (statement->output_statement.name);
284633965Sjdp      ldemul_set_output_arch ();
2847130561Sobrien      if (config.magic_demand_paged && !link_info.relocatable)
284833965Sjdp	output_bfd->flags |= D_PAGED;
284933965Sjdp      else
285033965Sjdp	output_bfd->flags &= ~D_PAGED;
285133965Sjdp      if (config.text_read_only)
285233965Sjdp	output_bfd->flags |= WP_TEXT;
285333965Sjdp      else
285433965Sjdp	output_bfd->flags &= ~WP_TEXT;
285533965Sjdp      if (link_info.traditional_format)
285633965Sjdp	output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
285733965Sjdp      else
285833965Sjdp	output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
285933965Sjdp      break;
286033965Sjdp
286133965Sjdp    case lang_target_statement_enum:
286233965Sjdp      current_target = statement->target_statement.target;
286333965Sjdp      break;
286433965Sjdp    default:
286533965Sjdp      break;
286633965Sjdp    }
286733965Sjdp}
286833965Sjdp
2869130561Sobrien/* Convert between addresses in bytes and sizes in octets.
2870130561Sobrien   For currently supported targets, octets_per_byte is always a power
2871130561Sobrien   of two, so we can use shifts.  */
2872130561Sobrien#define TO_ADDR(X) ((X) >> opb_shift)
2873130561Sobrien#define TO_SIZE(X) ((X) << opb_shift)
2874130561Sobrien
2875130561Sobrien/* Support the above.  */
2876130561Sobrienstatic unsigned int opb_shift = 0;
2877130561Sobrien
2878130561Sobrienstatic void
2879130561Sobrieninit_opb (void)
2880130561Sobrien{
2881130561Sobrien  unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
2882130561Sobrien					      ldfile_output_machine);
2883130561Sobrien  opb_shift = 0;
2884130561Sobrien  if (x > 1)
2885130561Sobrien    while ((x & 1) == 0)
2886130561Sobrien      {
2887130561Sobrien	x >>= 1;
2888130561Sobrien	++opb_shift;
2889130561Sobrien      }
2890130561Sobrien  ASSERT (x == 1);
2891130561Sobrien}
2892130561Sobrien
289333965Sjdp/* Open all the input files.  */
289433965Sjdp
289533965Sjdpstatic void
2896130561Sobrienopen_input_bfds (lang_statement_union_type *s, bfd_boolean force)
289733965Sjdp{
2898130561Sobrien  for (; s != NULL; s = s->header.next)
289933965Sjdp    {
290033965Sjdp      switch (s->header.type)
290133965Sjdp	{
290233965Sjdp	case lang_constructors_statement_enum:
290333965Sjdp	  open_input_bfds (constructor_list.head, force);
290433965Sjdp	  break;
290533965Sjdp	case lang_output_section_statement_enum:
290633965Sjdp	  open_input_bfds (s->output_section_statement.children.head, force);
290733965Sjdp	  break;
290833965Sjdp	case lang_wild_statement_enum:
290977298Sobrien	  /* Maybe we should load the file's symbols.  */
291033965Sjdp	  if (s->wild_statement.filename
291133965Sjdp	      && ! wildcardp (s->wild_statement.filename))
2912130561Sobrien	    lookup_name (s->wild_statement.filename);
291333965Sjdp	  open_input_bfds (s->wild_statement.children.head, force);
291433965Sjdp	  break;
291533965Sjdp	case lang_group_statement_enum:
291633965Sjdp	  {
291733965Sjdp	    struct bfd_link_hash_entry *undefs;
291833965Sjdp
291933965Sjdp	    /* We must continually search the entries in the group
292077298Sobrien	       until no new symbols are added to the list of undefined
292177298Sobrien	       symbols.  */
292233965Sjdp
292333965Sjdp	    do
292433965Sjdp	      {
292533965Sjdp		undefs = link_info.hash->undefs_tail;
2926130561Sobrien		open_input_bfds (s->group_statement.children.head, TRUE);
292733965Sjdp	      }
292833965Sjdp	    while (undefs != link_info.hash->undefs_tail);
292933965Sjdp	  }
293033965Sjdp	  break;
293133965Sjdp	case lang_target_statement_enum:
293233965Sjdp	  current_target = s->target_statement.target;
293333965Sjdp	  break;
293433965Sjdp	case lang_input_statement_enum:
293560484Sobrien	  if (s->input_statement.real)
293633965Sjdp	    {
293733965Sjdp	      lang_statement_list_type add;
293833965Sjdp
293933965Sjdp	      s->input_statement.target = current_target;
294033965Sjdp
294133965Sjdp	      /* If we are being called from within a group, and this
2942218822Sdim		 is an archive which has already been searched, then
2943218822Sdim		 force it to be researched unless the whole archive
294477298Sobrien		 has been loaded already.  */
294533965Sjdp	      if (force
294677298Sobrien		  && !s->input_statement.whole_archive
294733965Sjdp		  && s->input_statement.loaded
294833965Sjdp		  && bfd_check_format (s->input_statement.the_bfd,
294933965Sjdp				       bfd_archive))
2950130561Sobrien		s->input_statement.loaded = FALSE;
295133965Sjdp
295233965Sjdp	      lang_list_init (&add);
295333965Sjdp
295489857Sobrien	      if (! load_symbols (&s->input_statement, &add))
2955130561Sobrien		config.make_executable = FALSE;
295633965Sjdp
295733965Sjdp	      if (add.head != NULL)
295833965Sjdp		{
295989857Sobrien		  *add.tail = s->header.next;
296089857Sobrien		  s->header.next = add.head;
296133965Sjdp		}
296233965Sjdp	    }
296333965Sjdp	  break;
296433965Sjdp	default:
296533965Sjdp	  break;
296633965Sjdp	}
296733965Sjdp    }
296833965Sjdp}
296933965Sjdp
2970130561Sobrien/* Add a symbol to a hash of symbols used in DEFINED (NAME) expressions.  */
2971130561Sobrien
2972130561Sobrienvoid
2973130561Sobrienlang_track_definedness (const char *name)
2974130561Sobrien{
2975130561Sobrien  if (bfd_hash_lookup (&lang_definedness_table, name, TRUE, FALSE) == NULL)
2976130561Sobrien    einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name);
2977130561Sobrien}
2978130561Sobrien
2979130561Sobrien/* New-function for the definedness hash table.  */
2980130561Sobrien
2981130561Sobrienstatic struct bfd_hash_entry *
2982130561Sobrienlang_definedness_newfunc (struct bfd_hash_entry *entry,
2983130561Sobrien			  struct bfd_hash_table *table ATTRIBUTE_UNUSED,
2984130561Sobrien			  const char *name ATTRIBUTE_UNUSED)
2985130561Sobrien{
2986130561Sobrien  struct lang_definedness_hash_entry *ret
2987130561Sobrien    = (struct lang_definedness_hash_entry *) entry;
2988130561Sobrien
2989130561Sobrien  if (ret == NULL)
2990130561Sobrien    ret = (struct lang_definedness_hash_entry *)
2991130561Sobrien      bfd_hash_allocate (table, sizeof (struct lang_definedness_hash_entry));
2992130561Sobrien
2993130561Sobrien  if (ret == NULL)
2994130561Sobrien    einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name);
2995130561Sobrien
2996130561Sobrien  ret->iteration = -1;
2997130561Sobrien  return &ret->root;
2998130561Sobrien}
2999130561Sobrien
3000130561Sobrien/* Return the iteration when the definition of NAME was last updated.  A
3001130561Sobrien   value of -1 means that the symbol is not defined in the linker script
3002130561Sobrien   or the command line, but may be defined in the linker symbol table.  */
3003130561Sobrien
3004130561Sobrienint
3005130561Sobrienlang_symbol_definition_iteration (const char *name)
3006130561Sobrien{
3007130561Sobrien  struct lang_definedness_hash_entry *defentry
3008130561Sobrien    = (struct lang_definedness_hash_entry *)
3009130561Sobrien    bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE);
3010130561Sobrien
3011130561Sobrien  /* We've already created this one on the presence of DEFINED in the
3012130561Sobrien     script, so it can't be NULL unless something is borked elsewhere in
3013130561Sobrien     the code.  */
3014130561Sobrien  if (defentry == NULL)
3015130561Sobrien    FAIL ();
3016130561Sobrien
3017130561Sobrien  return defentry->iteration;
3018130561Sobrien}
3019130561Sobrien
3020130561Sobrien/* Update the definedness state of NAME.  */
3021130561Sobrien
3022130561Sobrienvoid
3023130561Sobrienlang_update_definedness (const char *name, struct bfd_link_hash_entry *h)
3024130561Sobrien{
3025130561Sobrien  struct lang_definedness_hash_entry *defentry
3026130561Sobrien    = (struct lang_definedness_hash_entry *)
3027130561Sobrien    bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE);
3028130561Sobrien
3029130561Sobrien  /* We don't keep track of symbols not tested with DEFINED.  */
3030130561Sobrien  if (defentry == NULL)
3031130561Sobrien    return;
3032130561Sobrien
3033130561Sobrien  /* If the symbol was already defined, and not from an earlier statement
3034130561Sobrien     iteration, don't update the definedness iteration, because that'd
3035130561Sobrien     make the symbol seem defined in the linker script at this point, and
3036130561Sobrien     it wasn't; it was defined in some object.  If we do anyway, DEFINED
3037130561Sobrien     would start to yield false before this point and the construct "sym =
3038130561Sobrien     DEFINED (sym) ? sym : X;" would change sym to X despite being defined
3039130561Sobrien     in an object.  */
3040130561Sobrien  if (h->type != bfd_link_hash_undefined
3041130561Sobrien      && h->type != bfd_link_hash_common
3042130561Sobrien      && h->type != bfd_link_hash_new
3043130561Sobrien      && defentry->iteration == -1)
3044130561Sobrien    return;
3045130561Sobrien
3046130561Sobrien  defentry->iteration = lang_statement_iteration;
3047130561Sobrien}
3048130561Sobrien
304977298Sobrien/* Add the supplied name to the symbol table as an undefined reference.
305094536Sobrien   This is a two step process as the symbol table doesn't even exist at
305194536Sobrien   the time the ld command line is processed.  First we put the name
305294536Sobrien   on a list, then, once the output file has been opened, transfer the
305394536Sobrien   name to the symbol table.  */
305494536Sobrien
3055104834Sobrientypedef struct bfd_sym_chain ldlang_undef_chain_list_type;
305633965Sjdp
3057104834Sobrien#define ldlang_undef_chain_list_head entry_symbol.next
305833965Sjdp
305933965Sjdpvoid
3060130561Sobrienldlang_add_undef (const char *const name)
306133965Sjdp{
306233965Sjdp  ldlang_undef_chain_list_type *new =
3063130561Sobrien    stat_alloc (sizeof (ldlang_undef_chain_list_type));
306433965Sjdp
306533965Sjdp  new->next = ldlang_undef_chain_list_head;
306633965Sjdp  ldlang_undef_chain_list_head = new;
306733965Sjdp
306878828Sobrien  new->name = xstrdup (name);
306994536Sobrien
307094536Sobrien  if (output_bfd != NULL)
307194536Sobrien    insert_undefined (new->name);
307233965Sjdp}
307333965Sjdp
307494536Sobrien/* Insert NAME as undefined in the symbol table.  */
307594536Sobrien
307694536Sobrienstatic void
3077130561Sobrieninsert_undefined (const char *name)
307894536Sobrien{
307994536Sobrien  struct bfd_link_hash_entry *h;
308094536Sobrien
3081130561Sobrien  h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE);
3082130561Sobrien  if (h == NULL)
308394536Sobrien    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
308494536Sobrien  if (h->type == bfd_link_hash_new)
308594536Sobrien    {
308694536Sobrien      h->type = bfd_link_hash_undefined;
308794536Sobrien      h->u.undef.abfd = NULL;
308894536Sobrien      bfd_link_add_undef (link_info.hash, h);
308994536Sobrien    }
309094536Sobrien}
309194536Sobrien
309233965Sjdp/* Run through the list of undefineds created above and place them
309333965Sjdp   into the linker hash table as undefined symbols belonging to the
309477298Sobrien   script file.  */
309577298Sobrien
309633965Sjdpstatic void
3097130561Sobrienlang_place_undefineds (void)
309833965Sjdp{
309933965Sjdp  ldlang_undef_chain_list_type *ptr;
310033965Sjdp
3101130561Sobrien  for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next)
3102130561Sobrien    insert_undefined (ptr->name);
310333965Sjdp}
310433965Sjdp
3105218822Sdim/* Check for all readonly or some readwrite sections.  */
3106218822Sdim
3107218822Sdimstatic void
3108218822Sdimcheck_input_sections
3109218822Sdim  (lang_statement_union_type *s,
3110218822Sdim   lang_output_section_statement_type *output_section_statement)
3111218822Sdim{
3112218822Sdim  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
3113218822Sdim    {
3114218822Sdim      switch (s->header.type)
3115218822Sdim      {
3116218822Sdim      case lang_wild_statement_enum:
3117218822Sdim	walk_wild (&s->wild_statement, check_section_callback,
3118218822Sdim		   output_section_statement);
3119218822Sdim	if (! output_section_statement->all_input_readonly)
3120218822Sdim	  return;
3121218822Sdim	break;
3122218822Sdim      case lang_constructors_statement_enum:
3123218822Sdim	check_input_sections (constructor_list.head,
3124218822Sdim			      output_section_statement);
3125218822Sdim	if (! output_section_statement->all_input_readonly)
3126218822Sdim	  return;
3127218822Sdim	break;
3128218822Sdim      case lang_group_statement_enum:
3129218822Sdim	check_input_sections (s->group_statement.children.head,
3130218822Sdim			      output_section_statement);
3131218822Sdim	if (! output_section_statement->all_input_readonly)
3132218822Sdim	  return;
3133218822Sdim	break;
3134218822Sdim      default:
3135218822Sdim	break;
3136218822Sdim      }
3137218822Sdim    }
3138218822Sdim}
3139218822Sdim
3140218822Sdim/* Update wildcard statements if needed.  */
3141218822Sdim
3142218822Sdimstatic void
3143218822Sdimupdate_wild_statements (lang_statement_union_type *s)
3144218822Sdim{
3145218822Sdim  struct wildcard_list *sec;
3146218822Sdim
3147218822Sdim  switch (sort_section)
3148218822Sdim    {
3149218822Sdim    default:
3150218822Sdim      FAIL ();
3151218822Sdim
3152218822Sdim    case none:
3153218822Sdim      break;
3154218822Sdim
3155218822Sdim    case by_name:
3156218822Sdim    case by_alignment:
3157218822Sdim      for (; s != NULL; s = s->header.next)
3158218822Sdim	{
3159218822Sdim	  switch (s->header.type)
3160218822Sdim	    {
3161218822Sdim	    default:
3162218822Sdim	      break;
3163218822Sdim
3164218822Sdim	    case lang_wild_statement_enum:
3165218822Sdim	      sec = s->wild_statement.section_list;
3166218822Sdim	      for (sec = s->wild_statement.section_list; sec != NULL;
3167218822Sdim		   sec = sec->next)
3168218822Sdim		{
3169218822Sdim		  switch (sec->spec.sorted)
3170218822Sdim		    {
3171218822Sdim		    case none:
3172218822Sdim		      sec->spec.sorted = sort_section;
3173218822Sdim		      break;
3174218822Sdim		    case by_name:
3175218822Sdim		      if (sort_section == by_alignment)
3176218822Sdim			sec->spec.sorted = by_name_alignment;
3177218822Sdim		      break;
3178218822Sdim		    case by_alignment:
3179218822Sdim		      if (sort_section == by_name)
3180218822Sdim			sec->spec.sorted = by_alignment_name;
3181218822Sdim		      break;
3182218822Sdim		    default:
3183218822Sdim		      break;
3184218822Sdim		    }
3185218822Sdim		}
3186218822Sdim	      break;
3187218822Sdim
3188218822Sdim	    case lang_constructors_statement_enum:
3189218822Sdim	      update_wild_statements (constructor_list.head);
3190218822Sdim	      break;
3191218822Sdim
3192218822Sdim	    case lang_output_section_statement_enum:
3193218822Sdim	      update_wild_statements
3194218822Sdim		(s->output_section_statement.children.head);
3195218822Sdim	      break;
3196218822Sdim
3197218822Sdim	    case lang_group_statement_enum:
3198218822Sdim	      update_wild_statements (s->group_statement.children.head);
3199218822Sdim	      break;
3200218822Sdim	    }
3201218822Sdim	}
3202218822Sdim      break;
3203218822Sdim    }
3204218822Sdim}
3205218822Sdim
3206130561Sobrien/* Open input files and attach to output sections.  */
320777298Sobrien
320833965Sjdpstatic void
3209130561Sobrienmap_input_to_output_sections
3210130561Sobrien  (lang_statement_union_type *s, const char *target,
3211218822Sdim   lang_output_section_statement_type *os)
321233965Sjdp{
3213218822Sdim  flagword flags;
3214218822Sdim
3215130561Sobrien  for (; s != NULL; s = s->header.next)
321633965Sjdp    {
321733965Sjdp      switch (s->header.type)
321833965Sjdp	{
321933965Sjdp	case lang_wild_statement_enum:
3220218822Sdim	  wild (&s->wild_statement, target, os);
322133965Sjdp	  break;
322233965Sjdp	case lang_constructors_statement_enum:
322333965Sjdp	  map_input_to_output_sections (constructor_list.head,
322433965Sjdp					target,
3225218822Sdim					os);
322633965Sjdp	  break;
322733965Sjdp	case lang_output_section_statement_enum:
3228218822Sdim	  if (s->output_section_statement.constraint)
3229218822Sdim	    {
3230218822Sdim	      if (s->output_section_statement.constraint != ONLY_IF_RW
3231218822Sdim		  && s->output_section_statement.constraint != ONLY_IF_RO)
3232218822Sdim		break;
3233218822Sdim	      s->output_section_statement.all_input_readonly = TRUE;
3234218822Sdim	      check_input_sections (s->output_section_statement.children.head,
3235218822Sdim				    &s->output_section_statement);
3236218822Sdim	      if ((s->output_section_statement.all_input_readonly
3237218822Sdim		   && s->output_section_statement.constraint == ONLY_IF_RW)
3238218822Sdim		  || (!s->output_section_statement.all_input_readonly
3239218822Sdim		      && s->output_section_statement.constraint == ONLY_IF_RO))
3240218822Sdim		{
3241218822Sdim		  s->output_section_statement.constraint = -1;
3242218822Sdim		  break;
3243218822Sdim		}
3244218822Sdim	    }
3245218822Sdim
324633965Sjdp	  map_input_to_output_sections (s->output_section_statement.children.head,
324733965Sjdp					target,
324833965Sjdp					&s->output_section_statement);
324933965Sjdp	  break;
325033965Sjdp	case lang_output_statement_enum:
325133965Sjdp	  break;
325233965Sjdp	case lang_target_statement_enum:
325333965Sjdp	  target = s->target_statement.target;
325433965Sjdp	  break;
325533965Sjdp	case lang_group_statement_enum:
325633965Sjdp	  map_input_to_output_sections (s->group_statement.children.head,
325733965Sjdp					target,
3258218822Sdim					os);
325933965Sjdp	  break;
3260130561Sobrien	case lang_data_statement_enum:
3261130561Sobrien	  /* Make sure that any sections mentioned in the expression
3262130561Sobrien	     are initialized.  */
3263130561Sobrien	  exp_init_os (s->data_statement.exp);
3264218822Sdim	  flags = SEC_HAS_CONTENTS;
3265218822Sdim	  /* The output section gets contents, and then we inspect for
3266218822Sdim	     any flags set in the input script which override any ALLOC.  */
3267218822Sdim	  if (!(os->flags & SEC_NEVER_LOAD))
3268218822Sdim	    flags |= SEC_ALLOC | SEC_LOAD;
3269218822Sdim	  if (os->bfd_section == NULL)
3270218822Sdim	    init_os (os, NULL, flags);
3271218822Sdim	  else
3272218822Sdim	    os->bfd_section->flags |= flags;
3273218822Sdim	  break;
3274218822Sdim	case lang_input_section_enum:
3275218822Sdim	  break;
327633965Sjdp	case lang_fill_statement_enum:
327733965Sjdp	case lang_object_symbols_statement_enum:
327833965Sjdp	case lang_reloc_statement_enum:
327933965Sjdp	case lang_padding_statement_enum:
328033965Sjdp	case lang_input_statement_enum:
3281218822Sdim	  if (os != NULL && os->bfd_section == NULL)
3282218822Sdim	    init_os (os, NULL, 0);
328333965Sjdp	  break;
328433965Sjdp	case lang_assignment_statement_enum:
3285218822Sdim	  if (os != NULL && os->bfd_section == NULL)
3286218822Sdim	    init_os (os, NULL, 0);
328733965Sjdp
328833965Sjdp	  /* Make sure that any sections mentioned in the assignment
328977298Sobrien	     are initialized.  */
329033965Sjdp	  exp_init_os (s->assignment_statement.exp);
329133965Sjdp	  break;
329233965Sjdp	case lang_afile_asection_pair_statement_enum:
329333965Sjdp	  FAIL ();
329433965Sjdp	  break;
329533965Sjdp	case lang_address_statement_enum:
3296218822Sdim	  /* Mark the specified section with the supplied address.
329733965Sjdp
3298218822Sdim	     If this section was actually a segment marker, then the
3299218822Sdim	     directive is ignored if the linker script explicitly
3300218822Sdim	     processed the segment marker.  Originally, the linker
3301218822Sdim	     treated segment directives (like -Ttext on the
3302218822Sdim	     command-line) as section directives.  We honor the
3303218822Sdim	     section directive semantics for backwards compatibilty;
3304218822Sdim	     linker scripts that do not specifically check for
3305218822Sdim	     SEGMENT_START automatically get the old semantics.  */
3306218822Sdim	  if (!s->address_statement.segment
3307218822Sdim	      || !s->address_statement.segment->used)
3308218822Sdim	    {
3309218822Sdim	      lang_output_section_statement_type *aos
3310218822Sdim		= (lang_output_section_statement_lookup
3311218822Sdim		   (s->address_statement.section_name));
3312218822Sdim
3313218822Sdim	      if (aos->bfd_section == NULL)
3314218822Sdim		init_os (aos, NULL, 0);
3315218822Sdim	      aos->addr_tree = s->address_statement.address;
3316218822Sdim	    }
331733965Sjdp	  break;
331833965Sjdp	}
331933965Sjdp    }
332033965Sjdp}
332133965Sjdp
3322104834Sobrien/* An output section might have been removed after its statement was
3323104834Sobrien   added.  For example, ldemul_before_allocation can remove dynamic
3324104834Sobrien   sections if they turn out to be not needed.  Clean them up here.  */
3325104834Sobrien
3326218822Sdimvoid
3327130561Sobrienstrip_excluded_output_sections (void)
3328104834Sobrien{
3329218822Sdim  lang_output_section_statement_type *os;
3330104834Sobrien
3331218822Sdim  /* Run lang_size_sections (if not already done).  */
3332218822Sdim  if (expld.phase != lang_mark_phase_enum)
3333104834Sobrien    {
3334218822Sdim      expld.phase = lang_mark_phase_enum;
3335218822Sdim      expld.dataseg.phase = exp_dataseg_none;
3336218822Sdim      one_lang_size_sections_pass (NULL, FALSE);
3337218822Sdim      lang_reset_memory_regions ();
3338218822Sdim    }
3339104834Sobrien
3340218822Sdim  for (os = &lang_output_section_statement.head->output_section_statement;
3341218822Sdim       os != NULL;
3342218822Sdim       os = os->next)
3343218822Sdim    {
3344218822Sdim      asection *output_section;
3345218822Sdim      bfd_boolean exclude;
3346218822Sdim
3347218822Sdim      if (os->constraint == -1)
3348218822Sdim	continue;
3349218822Sdim
3350218822Sdim      output_section = os->bfd_section;
3351218822Sdim      if (output_section == NULL)
3352218822Sdim	continue;
3353218822Sdim
3354218822Sdim      exclude = (output_section->rawsize == 0
3355218822Sdim		 && (output_section->flags & SEC_KEEP) == 0
3356218822Sdim		 && !bfd_section_removed_from_list (output_bfd,
3357218822Sdim						    output_section));
3358218822Sdim
3359218822Sdim      /* Some sections have not yet been sized, notably .gnu.version,
3360218822Sdim	 .dynsym, .dynstr and .hash.  These all have SEC_LINKER_CREATED
3361218822Sdim	 input sections, so don't drop output sections that have such
3362218822Sdim	 input sections unless they are also marked SEC_EXCLUDE.  */
3363218822Sdim      if (exclude && output_section->map_head.s != NULL)
3364104834Sobrien	{
3365218822Sdim	  asection *s;
3366104834Sobrien
3367218822Sdim	  for (s = output_section->map_head.s; s != NULL; s = s->map_head.s)
3368218822Sdim	    if ((s->flags & SEC_LINKER_CREATED) != 0
3369218822Sdim		&& (s->flags & SEC_EXCLUDE) == 0)
3370104834Sobrien	      {
3371218822Sdim		exclude = FALSE;
3372104834Sobrien		break;
3373104834Sobrien	      }
3374104834Sobrien	}
3375218822Sdim
3376218822Sdim      /* TODO: Don't just junk map_head.s, turn them into link_orders.  */
3377218822Sdim      output_section->map_head.link_order = NULL;
3378218822Sdim      output_section->map_tail.link_order = NULL;
3379218822Sdim
3380218822Sdim      if (exclude)
3381218822Sdim	{
3382218822Sdim	  /* We don't set bfd_section to NULL since bfd_section of the
3383218822Sdim	     removed output section statement may still be used.  */
3384218822Sdim	  if (!os->section_relative_symbol)
3385218822Sdim	    os->ignored = TRUE;
3386218822Sdim	  output_section->flags |= SEC_EXCLUDE;
3387218822Sdim	  bfd_section_list_remove (output_bfd, output_section);
3388218822Sdim	  output_bfd->section_count--;
3389218822Sdim	}
3390104834Sobrien    }
3391218822Sdim
3392218822Sdim  /* Stop future calls to lang_add_section from messing with map_head
3393218822Sdim     and map_tail link_order fields.  */
3394218822Sdim  stripped_excluded_sections = TRUE;
3395104834Sobrien}
3396104834Sobrien
3397104834Sobrienstatic void
3398130561Sobrienprint_output_section_statement
3399130561Sobrien  (lang_output_section_statement_type *output_section_statement)
340033965Sjdp{
340133965Sjdp  asection *section = output_section_statement->bfd_section;
340233965Sjdp  int len;
340333965Sjdp
340433965Sjdp  if (output_section_statement != abs_output_section)
340533965Sjdp    {
340633965Sjdp      minfo ("\n%s", output_section_statement->name);
340733965Sjdp
340833965Sjdp      if (section != NULL)
340933965Sjdp	{
341033965Sjdp	  print_dot = section->vma;
341133965Sjdp
341233965Sjdp	  len = strlen (output_section_statement->name);
341333965Sjdp	  if (len >= SECTION_NAME_MAP_LENGTH - 1)
341433965Sjdp	    {
341533965Sjdp	      print_nl ();
341633965Sjdp	      len = 0;
341733965Sjdp	    }
341833965Sjdp	  while (len < SECTION_NAME_MAP_LENGTH)
341933965Sjdp	    {
342033965Sjdp	      print_space ();
342133965Sjdp	      ++len;
342233965Sjdp	    }
342333965Sjdp
3424218822Sdim	  minfo ("0x%V %W", section->vma, section->size);
342533965Sjdp
3426218822Sdim	  if (section->vma != section->lma)
3427218822Sdim	    minfo (_(" load address 0x%V"), section->lma);
342833965Sjdp	}
342933965Sjdp
343033965Sjdp      print_nl ();
343133965Sjdp    }
343233965Sjdp
343333965Sjdp  print_statement_list (output_section_statement->children.head,
343433965Sjdp			output_section_statement);
343533965Sjdp}
343633965Sjdp
3437218822Sdim/* Scan for the use of the destination in the right hand side
3438218822Sdim   of an expression.  In such cases we will not compute the
3439218822Sdim   correct expression, since the value of DST that is used on
3440218822Sdim   the right hand side will be its final value, not its value
3441218822Sdim   just before this expression is evaluated.  */
3442218822Sdim
3443218822Sdimstatic bfd_boolean
3444218822Sdimscan_for_self_assignment (const char * dst, etree_type * rhs)
3445218822Sdim{
3446218822Sdim  if (rhs == NULL || dst == NULL)
3447218822Sdim    return FALSE;
3448218822Sdim
3449218822Sdim  switch (rhs->type.node_class)
3450218822Sdim    {
3451218822Sdim    case etree_binary:
3452218822Sdim      return scan_for_self_assignment (dst, rhs->binary.lhs)
3453218822Sdim	||   scan_for_self_assignment (dst, rhs->binary.rhs);
3454218822Sdim
3455218822Sdim    case etree_trinary:
3456218822Sdim      return scan_for_self_assignment (dst, rhs->trinary.lhs)
3457218822Sdim	||   scan_for_self_assignment (dst, rhs->trinary.rhs);
3458218822Sdim
3459218822Sdim    case etree_assign:
3460218822Sdim    case etree_provided:
3461218822Sdim    case etree_provide:
3462218822Sdim      if (strcmp (dst, rhs->assign.dst) == 0)
3463218822Sdim	return TRUE;
3464218822Sdim      return scan_for_self_assignment (dst, rhs->assign.src);
3465218822Sdim
3466218822Sdim    case etree_unary:
3467218822Sdim      return scan_for_self_assignment (dst, rhs->unary.child);
3468218822Sdim
3469218822Sdim    case etree_value:
3470218822Sdim      if (rhs->value.str)
3471218822Sdim	return strcmp (dst, rhs->value.str) == 0;
3472218822Sdim      return FALSE;
3473218822Sdim
3474218822Sdim    case etree_name:
3475218822Sdim      if (rhs->name.name)
3476218822Sdim	return strcmp (dst, rhs->name.name) == 0;
3477218822Sdim      return FALSE;
3478218822Sdim
3479218822Sdim    default:
3480218822Sdim      break;
3481218822Sdim    }
3482218822Sdim
3483218822Sdim  return FALSE;
3484218822Sdim}
3485218822Sdim
3486218822Sdim
348733965Sjdpstatic void
3488130561Sobrienprint_assignment (lang_assignment_statement_type *assignment,
3489130561Sobrien		  lang_output_section_statement_type *output_section)
349033965Sjdp{
3491218822Sdim  unsigned int i;
3492218822Sdim  bfd_boolean is_dot;
3493218822Sdim  bfd_boolean computation_is_valid = TRUE;
3494218822Sdim  etree_type *tree;
349533965Sjdp
349633965Sjdp  for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
349733965Sjdp    print_space ();
349833965Sjdp
3499218822Sdim  if (assignment->exp->type.node_class == etree_assert)
3500104834Sobrien    {
3501218822Sdim      is_dot = FALSE;
3502218822Sdim      tree = assignment->exp->assert_s.child;
3503218822Sdim      computation_is_valid = TRUE;
3504218822Sdim    }
3505218822Sdim  else
3506218822Sdim    {
3507218822Sdim      const char *dst = assignment->exp->assign.dst;
3508218822Sdim
3509218822Sdim      is_dot = (dst[0] == '.' && dst[1] == 0);
3510218822Sdim      tree = assignment->exp->assign.src;
3511218822Sdim      computation_is_valid = is_dot || (scan_for_self_assignment (dst, tree) == FALSE);
3512218822Sdim    }
3513218822Sdim
3514218822Sdim  exp_fold_tree (tree, output_section->bfd_section, &print_dot);
3515218822Sdim  if (expld.result.valid_p)
3516218822Sdim    {
3517104834Sobrien      bfd_vma value;
3518104834Sobrien
3519218822Sdim      if (computation_is_valid)
3520218822Sdim	{
3521218822Sdim	  value = expld.result.value;
3522104834Sobrien
3523218822Sdim	  if (expld.result.section)
3524218822Sdim	    value += expld.result.section->vma;
3525218822Sdim
3526218822Sdim	  minfo ("0x%V", value);
3527218822Sdim	  if (is_dot)
3528218822Sdim	    print_dot = value;
3529218822Sdim	}
3530218822Sdim      else
3531218822Sdim	{
3532218822Sdim	  struct bfd_link_hash_entry *h;
3533218822Sdim
3534218822Sdim	  h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst,
3535218822Sdim				    FALSE, FALSE, TRUE);
3536218822Sdim	  if (h)
3537218822Sdim	    {
3538218822Sdim	      value = h->u.def.value;
3539218822Sdim
3540218822Sdim	      if (expld.result.section)
3541218822Sdim	      value += expld.result.section->vma;
3542218822Sdim
3543218822Sdim	      minfo ("[0x%V]", value);
3544218822Sdim	    }
3545218822Sdim	  else
3546218822Sdim	    minfo ("[unresolved]");
3547218822Sdim	}
3548104834Sobrien    }
354933965Sjdp  else
355033965Sjdp    {
355133965Sjdp      minfo ("*undef*   ");
355233965Sjdp#ifdef BFD64
355333965Sjdp      minfo ("        ");
355433965Sjdp#endif
355533965Sjdp    }
355633965Sjdp
355733965Sjdp  minfo ("                ");
355833965Sjdp  exp_print_tree (assignment->exp);
355933965Sjdp  print_nl ();
356033965Sjdp}
356133965Sjdp
356233965Sjdpstatic void
3563130561Sobrienprint_input_statement (lang_input_statement_type *statm)
356433965Sjdp{
3565130561Sobrien  if (statm->filename != NULL)
356633965Sjdp    {
356733965Sjdp      fprintf (config.map_file, "LOAD %s\n", statm->filename);
356833965Sjdp    }
356933965Sjdp}
357033965Sjdp
357133965Sjdp/* Print all symbols defined in a particular section.  This is called
3572218822Sdim   via bfd_link_hash_traverse, or by print_all_symbols.  */
357333965Sjdp
3574130561Sobrienstatic bfd_boolean
3575130561Sobrienprint_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr)
357633965Sjdp{
3577130561Sobrien  asection *sec = ptr;
357833965Sjdp
357933965Sjdp  if ((hash_entry->type == bfd_link_hash_defined
358033965Sjdp       || hash_entry->type == bfd_link_hash_defweak)
358133965Sjdp      && sec == hash_entry->u.def.section)
358233965Sjdp    {
358333965Sjdp      int i;
358433965Sjdp
358533965Sjdp      for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
358633965Sjdp	print_space ();
358733965Sjdp      minfo ("0x%V   ",
358833965Sjdp	     (hash_entry->u.def.value
358933965Sjdp	      + hash_entry->u.def.section->output_offset
359033965Sjdp	      + hash_entry->u.def.section->output_section->vma));
359133965Sjdp
359233965Sjdp      minfo ("             %T\n", hash_entry->root.string);
359333965Sjdp    }
359433965Sjdp
3595130561Sobrien  return TRUE;
359633965Sjdp}
359733965Sjdp
3598218822Sdimstatic void
3599218822Sdimprint_all_symbols (asection *sec)
3600218822Sdim{
3601218822Sdim  struct fat_user_section_struct *ud = get_userdata (sec);
3602218822Sdim  struct map_symbol_def *def;
3603218822Sdim
3604218822Sdim  if (!ud)
3605218822Sdim    return;
3606218822Sdim
3607218822Sdim  *ud->map_symbol_def_tail = 0;
3608218822Sdim  for (def = ud->map_symbol_def_head; def; def = def->next)
3609218822Sdim    print_one_symbol (def->entry, sec);
3610218822Sdim}
3611218822Sdim
361233965Sjdp/* Print information about an input section to the map file.  */
361333965Sjdp
361433965Sjdpstatic void
3615218822Sdimprint_input_section (asection *i)
361633965Sjdp{
3617218822Sdim  bfd_size_type size = i->size;
3618218822Sdim  int len;
3619218822Sdim  bfd_vma addr;
3620130561Sobrien
3621130561Sobrien  init_opb ();
3622218822Sdim
3623218822Sdim  print_space ();
3624218822Sdim  minfo ("%s", i->name);
3625218822Sdim
3626218822Sdim  len = 1 + strlen (i->name);
3627218822Sdim  if (len >= SECTION_NAME_MAP_LENGTH - 1)
362833965Sjdp    {
3629218822Sdim      print_nl ();
3630218822Sdim      len = 0;
3631218822Sdim    }
3632218822Sdim  while (len < SECTION_NAME_MAP_LENGTH)
3633218822Sdim    {
363433965Sjdp      print_space ();
3635218822Sdim      ++len;
3636218822Sdim    }
363733965Sjdp
3638218822Sdim  if (i->output_section != NULL && i->output_section->owner == output_bfd)
3639218822Sdim    addr = i->output_section->vma + i->output_offset;
3640218822Sdim  else
3641218822Sdim    {
3642218822Sdim      addr = print_dot;
3643218822Sdim      size = 0;
3644218822Sdim    }
364533965Sjdp
3646218822Sdim  minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner);
364733965Sjdp
3648218822Sdim  if (size != i->rawsize && i->rawsize != 0)
3649218822Sdim    {
3650218822Sdim      len = SECTION_NAME_MAP_LENGTH + 3;
365133965Sjdp#ifdef BFD64
3652218822Sdim      len += 16;
365333965Sjdp#else
3654218822Sdim      len += 8;
365533965Sjdp#endif
3656218822Sdim      while (len > 0)
3657218822Sdim	{
3658218822Sdim	  print_space ();
3659218822Sdim	  --len;
3660218822Sdim	}
366133965Sjdp
3662218822Sdim      minfo (_("%W (size before relaxing)\n"), i->rawsize);
3663218822Sdim    }
366433965Sjdp
3665218822Sdim  if (i->output_section != NULL && i->output_section->owner == output_bfd)
3666218822Sdim    {
3667218822Sdim      if (link_info.reduce_memory_overheads)
3668218822Sdim	bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
3669218822Sdim      else
3670218822Sdim	print_all_symbols (i);
367133965Sjdp
3672218822Sdim      print_dot = addr + TO_ADDR (size);
367333965Sjdp    }
367433965Sjdp}
367533965Sjdp
367633965Sjdpstatic void
3677130561Sobrienprint_fill_statement (lang_fill_statement_type *fill)
367833965Sjdp{
3679104834Sobrien  size_t size;
3680104834Sobrien  unsigned char *p;
3681104834Sobrien  fputs (" FILL mask 0x", config.map_file);
3682104834Sobrien  for (p = fill->fill->data, size = fill->fill->size; size != 0; p++, size--)
3683104834Sobrien    fprintf (config.map_file, "%02x", *p);
3684104834Sobrien  fputs ("\n", config.map_file);
368533965Sjdp}
368633965Sjdp
368733965Sjdpstatic void
3688130561Sobrienprint_data_statement (lang_data_statement_type *data)
368933965Sjdp{
369033965Sjdp  int i;
369133965Sjdp  bfd_vma addr;
369233965Sjdp  bfd_size_type size;
369333965Sjdp  const char *name;
369433965Sjdp
3695130561Sobrien  init_opb ();
369633965Sjdp  for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
369733965Sjdp    print_space ();
369833965Sjdp
3699218822Sdim  addr = data->output_offset;
370033965Sjdp  if (data->output_section != NULL)
370133965Sjdp    addr += data->output_section->vma;
370233965Sjdp
370333965Sjdp  switch (data->type)
370433965Sjdp    {
370533965Sjdp    default:
370633965Sjdp      abort ();
370733965Sjdp    case BYTE:
370833965Sjdp      size = BYTE_SIZE;
370933965Sjdp      name = "BYTE";
371033965Sjdp      break;
371133965Sjdp    case SHORT:
371233965Sjdp      size = SHORT_SIZE;
371333965Sjdp      name = "SHORT";
371433965Sjdp      break;
371533965Sjdp    case LONG:
371633965Sjdp      size = LONG_SIZE;
371733965Sjdp      name = "LONG";
371833965Sjdp      break;
371933965Sjdp    case QUAD:
372033965Sjdp      size = QUAD_SIZE;
372133965Sjdp      name = "QUAD";
372233965Sjdp      break;
372338889Sjdp    case SQUAD:
372438889Sjdp      size = QUAD_SIZE;
372538889Sjdp      name = "SQUAD";
372638889Sjdp      break;
372733965Sjdp    }
372833965Sjdp
372933965Sjdp  minfo ("0x%V %W %s 0x%v", addr, size, name, data->value);
373033965Sjdp
373133965Sjdp  if (data->exp->type.node_class != etree_value)
373233965Sjdp    {
373333965Sjdp      print_space ();
373433965Sjdp      exp_print_tree (data->exp);
373533965Sjdp    }
373633965Sjdp
373733965Sjdp  print_nl ();
373833965Sjdp
3739130561Sobrien  print_dot = addr + TO_ADDR (size);
374033965Sjdp}
374133965Sjdp
374233965Sjdp/* Print an address statement.  These are generated by options like
374333965Sjdp   -Ttext.  */
374433965Sjdp
374533965Sjdpstatic void
3746130561Sobrienprint_address_statement (lang_address_statement_type *address)
374733965Sjdp{
374860484Sobrien  minfo (_("Address of section %s set to "), address->section_name);
374933965Sjdp  exp_print_tree (address->address);
375033965Sjdp  print_nl ();
375133965Sjdp}
375233965Sjdp
375333965Sjdp/* Print a reloc statement.  */
375433965Sjdp
375533965Sjdpstatic void
3756130561Sobrienprint_reloc_statement (lang_reloc_statement_type *reloc)
375733965Sjdp{
375833965Sjdp  int i;
375933965Sjdp  bfd_vma addr;
376033965Sjdp  bfd_size_type size;
376133965Sjdp
3762130561Sobrien  init_opb ();
376333965Sjdp  for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
376433965Sjdp    print_space ();
376533965Sjdp
3766218822Sdim  addr = reloc->output_offset;
376733965Sjdp  if (reloc->output_section != NULL)
376833965Sjdp    addr += reloc->output_section->vma;
376933965Sjdp
377033965Sjdp  size = bfd_get_reloc_size (reloc->howto);
377133965Sjdp
377233965Sjdp  minfo ("0x%V %W RELOC %s ", addr, size, reloc->howto->name);
377333965Sjdp
377433965Sjdp  if (reloc->name != NULL)
377533965Sjdp    minfo ("%s+", reloc->name);
377633965Sjdp  else
377733965Sjdp    minfo ("%s+", reloc->section->name);
377833965Sjdp
377933965Sjdp  exp_print_tree (reloc->addend_exp);
378033965Sjdp
378133965Sjdp  print_nl ();
378233965Sjdp
3783130561Sobrien  print_dot = addr + TO_ADDR (size);
378477298Sobrien}
378533965Sjdp
378633965Sjdpstatic void
3787130561Sobrienprint_padding_statement (lang_padding_statement_type *s)
378833965Sjdp{
378933965Sjdp  int len;
379033965Sjdp  bfd_vma addr;
379133965Sjdp
3792130561Sobrien  init_opb ();
379333965Sjdp  minfo (" *fill*");
379433965Sjdp
379533965Sjdp  len = sizeof " *fill*" - 1;
379633965Sjdp  while (len < SECTION_NAME_MAP_LENGTH)
379733965Sjdp    {
379833965Sjdp      print_space ();
379933965Sjdp      ++len;
380033965Sjdp    }
380133965Sjdp
380233965Sjdp  addr = s->output_offset;
380333965Sjdp  if (s->output_section != NULL)
380433965Sjdp    addr += s->output_section->vma;
3805218822Sdim  minfo ("0x%V %W ", addr, (bfd_vma) s->size);
380633965Sjdp
3807104834Sobrien  if (s->fill->size != 0)
3808104834Sobrien    {
3809104834Sobrien      size_t size;
3810104834Sobrien      unsigned char *p;
3811104834Sobrien      for (p = s->fill->data, size = s->fill->size; size != 0; p++, size--)
3812104834Sobrien	fprintf (config.map_file, "%02x", *p);
3813104834Sobrien    }
381433965Sjdp
381533965Sjdp  print_nl ();
381633965Sjdp
3817130561Sobrien  print_dot = addr + TO_ADDR (s->size);
381833965Sjdp}
381933965Sjdp
382033965Sjdpstatic void
3821130561Sobrienprint_wild_statement (lang_wild_statement_type *w,
3822130561Sobrien		      lang_output_section_statement_type *os)
382333965Sjdp{
382489857Sobrien  struct wildcard_list *sec;
382589857Sobrien
382633965Sjdp  print_space ();
382733965Sjdp
382860484Sobrien  if (w->filenames_sorted)
382960484Sobrien    minfo ("SORT(");
383077298Sobrien  if (w->filename != NULL)
383133965Sjdp    minfo ("%s", w->filename);
383233965Sjdp  else
383333965Sjdp    minfo ("*");
383460484Sobrien  if (w->filenames_sorted)
383560484Sobrien    minfo (")");
383633965Sjdp
383760484Sobrien  minfo ("(");
383889857Sobrien  for (sec = w->section_list; sec; sec = sec->next)
383989857Sobrien    {
384089857Sobrien      if (sec->spec.sorted)
384189857Sobrien	minfo ("SORT(");
384289857Sobrien      if (sec->spec.exclude_name_list != NULL)
384389857Sobrien	{
384489857Sobrien	  name_list *tmp;
3845102729Sobrien	  minfo ("EXCLUDE_FILE(%s", sec->spec.exclude_name_list->name);
384689857Sobrien	  for (tmp = sec->spec.exclude_name_list->next; tmp; tmp = tmp->next)
3847102729Sobrien	    minfo (" %s", tmp->name);
3848102729Sobrien	  minfo (") ");
384989857Sobrien	}
385089857Sobrien      if (sec->spec.name != NULL)
385189857Sobrien	minfo ("%s", sec->spec.name);
385289857Sobrien      else
385389857Sobrien	minfo ("*");
385489857Sobrien      if (sec->spec.sorted)
385589857Sobrien	minfo (")");
3856102729Sobrien      if (sec->next)
3857102729Sobrien	minfo (" ");
385889857Sobrien    }
385960484Sobrien  minfo (")");
386033965Sjdp
386133965Sjdp  print_nl ();
386233965Sjdp
386333965Sjdp  print_statement_list (w->children.head, os);
386433965Sjdp}
386533965Sjdp
386633965Sjdp/* Print a group statement.  */
386733965Sjdp
386833965Sjdpstatic void
3869130561Sobrienprint_group (lang_group_statement_type *s,
3870130561Sobrien	     lang_output_section_statement_type *os)
387133965Sjdp{
387233965Sjdp  fprintf (config.map_file, "START GROUP\n");
387333965Sjdp  print_statement_list (s->children.head, os);
387433965Sjdp  fprintf (config.map_file, "END GROUP\n");
387533965Sjdp}
387633965Sjdp
387733965Sjdp/* Print the list of statements in S.
387833965Sjdp   This can be called for any statement type.  */
387933965Sjdp
388033965Sjdpstatic void
3881130561Sobrienprint_statement_list (lang_statement_union_type *s,
3882130561Sobrien		      lang_output_section_statement_type *os)
388333965Sjdp{
388433965Sjdp  while (s != NULL)
388533965Sjdp    {
388633965Sjdp      print_statement (s, os);
388789857Sobrien      s = s->header.next;
388833965Sjdp    }
388933965Sjdp}
389033965Sjdp
389133965Sjdp/* Print the first statement in statement list S.
389233965Sjdp   This can be called for any statement type.  */
389333965Sjdp
389433965Sjdpstatic void
3895130561Sobrienprint_statement (lang_statement_union_type *s,
3896130561Sobrien		 lang_output_section_statement_type *os)
389733965Sjdp{
389833965Sjdp  switch (s->header.type)
389933965Sjdp    {
390033965Sjdp    default:
390160484Sobrien      fprintf (config.map_file, _("Fail with %d\n"), s->header.type);
390233965Sjdp      FAIL ();
390333965Sjdp      break;
390433965Sjdp    case lang_constructors_statement_enum:
390533965Sjdp      if (constructor_list.head != NULL)
390633965Sjdp	{
390760484Sobrien	  if (constructors_sorted)
390860484Sobrien	    minfo (" SORT (CONSTRUCTORS)\n");
390960484Sobrien	  else
391060484Sobrien	    minfo (" CONSTRUCTORS\n");
391133965Sjdp	  print_statement_list (constructor_list.head, os);
391233965Sjdp	}
391333965Sjdp      break;
391433965Sjdp    case lang_wild_statement_enum:
391533965Sjdp      print_wild_statement (&s->wild_statement, os);
391633965Sjdp      break;
391733965Sjdp    case lang_address_statement_enum:
391833965Sjdp      print_address_statement (&s->address_statement);
391933965Sjdp      break;
392033965Sjdp    case lang_object_symbols_statement_enum:
392133965Sjdp      minfo (" CREATE_OBJECT_SYMBOLS\n");
392233965Sjdp      break;
392333965Sjdp    case lang_fill_statement_enum:
392433965Sjdp      print_fill_statement (&s->fill_statement);
392533965Sjdp      break;
392633965Sjdp    case lang_data_statement_enum:
392733965Sjdp      print_data_statement (&s->data_statement);
392833965Sjdp      break;
392933965Sjdp    case lang_reloc_statement_enum:
393033965Sjdp      print_reloc_statement (&s->reloc_statement);
393133965Sjdp      break;
393233965Sjdp    case lang_input_section_enum:
3933218822Sdim      print_input_section (s->input_section.section);
393433965Sjdp      break;
393533965Sjdp    case lang_padding_statement_enum:
393633965Sjdp      print_padding_statement (&s->padding_statement);
393733965Sjdp      break;
393833965Sjdp    case lang_output_section_statement_enum:
393933965Sjdp      print_output_section_statement (&s->output_section_statement);
394033965Sjdp      break;
394133965Sjdp    case lang_assignment_statement_enum:
394233965Sjdp      print_assignment (&s->assignment_statement, os);
394333965Sjdp      break;
394433965Sjdp    case lang_target_statement_enum:
394533965Sjdp      fprintf (config.map_file, "TARGET(%s)\n", s->target_statement.target);
394633965Sjdp      break;
394733965Sjdp    case lang_output_statement_enum:
394833965Sjdp      minfo ("OUTPUT(%s", s->output_statement.name);
394933965Sjdp      if (output_target != NULL)
395033965Sjdp	minfo (" %s", output_target);
395133965Sjdp      minfo (")\n");
395233965Sjdp      break;
395333965Sjdp    case lang_input_statement_enum:
395433965Sjdp      print_input_statement (&s->input_statement);
395533965Sjdp      break;
395633965Sjdp    case lang_group_statement_enum:
395733965Sjdp      print_group (&s->group_statement, os);
395833965Sjdp      break;
395933965Sjdp    case lang_afile_asection_pair_statement_enum:
396033965Sjdp      FAIL ();
396133965Sjdp      break;
396233965Sjdp    }
396333965Sjdp}
396433965Sjdp
396533965Sjdpstatic void
3966130561Sobrienprint_statements (void)
396733965Sjdp{
396833965Sjdp  print_statement_list (statement_list.head, abs_output_section);
396933965Sjdp}
397033965Sjdp
397133965Sjdp/* Print the first N statements in statement list S to STDERR.
397233965Sjdp   If N == 0, nothing is printed.
397333965Sjdp   If N < 0, the entire list is printed.
397433965Sjdp   Intended to be called from GDB.  */
397533965Sjdp
397633965Sjdpvoid
3977130561Sobriendprint_statement (lang_statement_union_type *s, int n)
397833965Sjdp{
397933965Sjdp  FILE *map_save = config.map_file;
398033965Sjdp
398133965Sjdp  config.map_file = stderr;
398233965Sjdp
398333965Sjdp  if (n < 0)
398433965Sjdp    print_statement_list (s, abs_output_section);
398533965Sjdp  else
398633965Sjdp    {
398733965Sjdp      while (s && --n >= 0)
398833965Sjdp	{
398933965Sjdp	  print_statement (s, abs_output_section);
399089857Sobrien	  s = s->header.next;
399133965Sjdp	}
399233965Sjdp    }
399333965Sjdp
399433965Sjdp  config.map_file = map_save;
399533965Sjdp}
399633965Sjdp
399789857Sobrienstatic void
3998130561Sobrieninsert_pad (lang_statement_union_type **ptr,
3999130561Sobrien	    fill_type *fill,
4000130561Sobrien	    unsigned int alignment_needed,
4001130561Sobrien	    asection *output_section,
4002130561Sobrien	    bfd_vma dot)
400333965Sjdp{
4004104834Sobrien  static fill_type zero_fill = { 1, { 0 } };
4005218822Sdim  lang_statement_union_type *pad = NULL;
400633965Sjdp
4007218822Sdim  if (ptr != &statement_list.head)
4008218822Sdim    pad = ((lang_statement_union_type *)
4009218822Sdim	   ((char *) ptr - offsetof (lang_statement_union_type, header.next)));
4010218822Sdim  if (pad != NULL
401189857Sobrien      && pad->header.type == lang_padding_statement_enum
401289857Sobrien      && pad->padding_statement.output_section == output_section)
401333965Sjdp    {
4014218822Sdim      /* Use the existing pad statement.  */
401533965Sjdp    }
4016218822Sdim  else if ((pad = *ptr) != NULL
4017218822Sdim      && pad->header.type == lang_padding_statement_enum
4018218822Sdim      && pad->padding_statement.output_section == output_section)
4019218822Sdim    {
4020218822Sdim      /* Use the existing pad statement.  */
4021218822Sdim    }
402289857Sobrien  else
402333965Sjdp    {
402489857Sobrien      /* Make a new padding statement, linked into existing chain.  */
4025130561Sobrien      pad = stat_alloc (sizeof (lang_padding_statement_type));
402689857Sobrien      pad->header.next = *ptr;
402789857Sobrien      *ptr = pad;
402889857Sobrien      pad->header.type = lang_padding_statement_enum;
402989857Sobrien      pad->padding_statement.output_section = output_section;
4030130561Sobrien      if (fill == NULL)
4031104834Sobrien	fill = &zero_fill;
403289857Sobrien      pad->padding_statement.fill = fill;
403333965Sjdp    }
403489857Sobrien  pad->padding_statement.output_offset = dot - output_section->vma;
403589857Sobrien  pad->padding_statement.size = alignment_needed;
4036218822Sdim  output_section->size += alignment_needed;
403733965Sjdp}
403833965Sjdp
403977298Sobrien/* Work out how much this section will move the dot point.  */
404077298Sobrien
404133965Sjdpstatic bfd_vma
4042218822Sdimsize_input_section
4043218822Sdim  (lang_statement_union_type **this_ptr,
4044218822Sdim   lang_output_section_statement_type *output_section_statement,
4045218822Sdim   fill_type *fill,
4046218822Sdim   bfd_vma dot)
404733965Sjdp{
404833965Sjdp  lang_input_section_type *is = &((*this_ptr)->input_section);
404933965Sjdp  asection *i = is->section;
405033965Sjdp
4051218822Sdim  if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
4052218822Sdim      && (i->flags & SEC_EXCLUDE) == 0)
405333965Sjdp    {
405489857Sobrien      unsigned int alignment_needed;
405589857Sobrien      asection *o;
405689857Sobrien
405789857Sobrien      /* Align this section first to the input sections requirement,
405889857Sobrien	 then to the output section's requirement.  If this alignment
405989857Sobrien	 is greater than any seen before, then record it too.  Perform
406089857Sobrien	 the alignment by inserting a magic 'padding' statement.  */
406189857Sobrien
406233965Sjdp      if (output_section_statement->subsection_alignment != -1)
406389857Sobrien	i->alignment_power = output_section_statement->subsection_alignment;
406433965Sjdp
406589857Sobrien      o = output_section_statement->bfd_section;
406689857Sobrien      if (o->alignment_power < i->alignment_power)
406789857Sobrien	o->alignment_power = i->alignment_power;
406833965Sjdp
406989857Sobrien      alignment_needed = align_power (dot, i->alignment_power) - dot;
407089857Sobrien
407189857Sobrien      if (alignment_needed != 0)
407289857Sobrien	{
4073130561Sobrien	  insert_pad (this_ptr, fill, TO_SIZE (alignment_needed), o, dot);
407489857Sobrien	  dot += alignment_needed;
407589857Sobrien	}
407689857Sobrien
407777298Sobrien      /* Remember where in the output section this input section goes.  */
407833965Sjdp
407989857Sobrien      i->output_offset = dot - o->vma;
408033965Sjdp
408177298Sobrien      /* Mark how big the output section must be to contain this now.  */
4082218822Sdim      dot += TO_ADDR (i->size);
4083218822Sdim      o->size = TO_SIZE (dot - o->vma);
408433965Sjdp    }
408533965Sjdp  else
408633965Sjdp    {
408733965Sjdp      i->output_offset = i->vma - output_section_statement->bfd_section->vma;
408833965Sjdp    }
408933965Sjdp
409033965Sjdp  return dot;
409133965Sjdp}
409233965Sjdp
4093218822Sdimstatic int
4094218822Sdimsort_sections_by_lma (const void *arg1, const void *arg2)
4095218822Sdim{
4096218822Sdim  const asection *sec1 = *(const asection **) arg1;
4097218822Sdim  const asection *sec2 = *(const asection **) arg2;
409860484Sobrien
4099218822Sdim  if (bfd_section_lma (sec1->owner, sec1)
4100218822Sdim      < bfd_section_lma (sec2->owner, sec2))
4101218822Sdim    return -1;
4102218822Sdim  else if (bfd_section_lma (sec1->owner, sec1)
4103218822Sdim	   > bfd_section_lma (sec2->owner, sec2))
4104218822Sdim    return 1;
4105218822Sdim
4106218822Sdim  return 0;
4107218822Sdim}
4108218822Sdim
4109218822Sdim#define IGNORE_SECTION(s) \
4110218822Sdim  ((s->flags & SEC_NEVER_LOAD) != 0				\
4111218822Sdim   || (s->flags & SEC_ALLOC) == 0				\
4112218822Sdim   || ((s->flags & SEC_THREAD_LOCAL) != 0			\
4113218822Sdim	&& (s->flags & SEC_LOAD) == 0))
4114218822Sdim
411560484Sobrien/* Check to see if any allocated sections overlap with other allocated
4116218822Sdim   sections.  This can happen if a linker script specifies the output
4117218822Sdim   section addresses of the two sections.  */
411877298Sobrien
411960484Sobrienstatic void
4120130561Sobrienlang_check_section_addresses (void)
412160484Sobrien{
4122218822Sdim  asection *s, *os;
4123218822Sdim  asection **sections, **spp;
4124218822Sdim  unsigned int count;
4125218822Sdim  bfd_vma s_start;
4126218822Sdim  bfd_vma s_end;
4127218822Sdim  bfd_vma os_start;
4128218822Sdim  bfd_vma os_end;
4129218822Sdim  bfd_size_type amt;
413060484Sobrien
4131218822Sdim  if (bfd_count_sections (output_bfd) <= 1)
4132218822Sdim    return;
4133218822Sdim
4134218822Sdim  amt = bfd_count_sections (output_bfd) * sizeof (asection *);
4135218822Sdim  sections = xmalloc (amt);
4136218822Sdim
413760484Sobrien  /* Scan all sections in the output list.  */
4138218822Sdim  count = 0;
413960484Sobrien  for (s = output_bfd->sections; s != NULL; s = s->next)
414060484Sobrien    {
4141218822Sdim      /* Only consider loadable sections with real contents.  */
4142218822Sdim      if (IGNORE_SECTION (s) || s->size == 0)
414360484Sobrien	continue;
414477298Sobrien
4145218822Sdim      sections[count] = s;
4146218822Sdim      count++;
4147218822Sdim    }
414877298Sobrien
4149218822Sdim  if (count <= 1)
4150218822Sdim    return;
415160484Sobrien
4152218822Sdim  qsort (sections, (size_t) count, sizeof (asection *),
4153218822Sdim	 sort_sections_by_lma);
415477298Sobrien
4155218822Sdim  spp = sections;
4156218822Sdim  s = *spp++;
4157218822Sdim  s_start = bfd_section_lma (output_bfd, s);
4158218822Sdim  s_end = s_start + TO_ADDR (s->size) - 1;
4159218822Sdim  for (count--; count; count--)
4160218822Sdim    {
4161218822Sdim      /* We must check the sections' LMA addresses not their VMA
4162218822Sdim	 addresses because overlay sections can have overlapping VMAs
4163218822Sdim	 but they must have distinct LMAs.  */
4164218822Sdim      os = s;
4165218822Sdim      os_start = s_start;
4166218822Sdim      os_end = s_end;
4167218822Sdim      s = *spp++;
4168218822Sdim      s_start = bfd_section_lma (output_bfd, s);
4169218822Sdim      s_end = s_start + TO_ADDR (s->size) - 1;
417077298Sobrien
4171218822Sdim      /* Look for an overlap.  */
4172218822Sdim      if (s_end >= os_start && s_start <= os_end)
4173218822Sdim	einfo (_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
4174218822Sdim	       s->name, s_start, s_end, os->name, os_start, os_end);
4175218822Sdim    }
417677298Sobrien
4177218822Sdim  free (sections);
417860484Sobrien}
417960484Sobrien
418060484Sobrien/* Make sure the new address is within the region.  We explicitly permit the
418160484Sobrien   current address to be at the exact end of the region when the address is
418260484Sobrien   non-zero, in case the region is at the end of addressable memory and the
418377298Sobrien   calculation wraps around.  */
418460484Sobrien
418560484Sobrienstatic void
4186130561Sobrienos_region_check (lang_output_section_statement_type *os,
4187130561Sobrien		 lang_memory_region_type *region,
4188130561Sobrien		 etree_type *tree,
4189130561Sobrien		 bfd_vma base)
419060484Sobrien{
419160484Sobrien  if ((region->current < region->origin
419260484Sobrien       || (region->current - region->origin > region->length))
419360484Sobrien      && ((region->current != region->origin + region->length)
4194104834Sobrien	  || base == 0))
419560484Sobrien    {
4196130561Sobrien      if (tree != NULL)
4197104834Sobrien	{
4198218822Sdim	  einfo (_("%X%P: address 0x%v of %B section %s"
4199218822Sdim		   " is not within region %s\n"),
4200104834Sobrien		 region->current,
4201104834Sobrien		 os->bfd_section->owner,
4202104834Sobrien		 os->bfd_section->name,
4203104834Sobrien		 region->name);
4204104834Sobrien	}
420560484Sobrien      else
4206104834Sobrien	{
4207104834Sobrien	  einfo (_("%X%P: region %s is full (%B section %s)\n"),
4208104834Sobrien		 region->name,
4209104834Sobrien		 os->bfd_section->owner,
4210104834Sobrien		 os->bfd_section->name);
4211104834Sobrien	}
421260484Sobrien      /* Reset the region pointer.  */
421360484Sobrien      region->current = region->origin;
421460484Sobrien    }
421560484Sobrien}
421660484Sobrien
421733965Sjdp/* Set the sizes for all the output sections.  */
421833965Sjdp
4219104834Sobrienstatic bfd_vma
4220130561Sobrienlang_size_sections_1
4221130561Sobrien  (lang_statement_union_type *s,
4222130561Sobrien   lang_output_section_statement_type *output_section_statement,
4223130561Sobrien   lang_statement_union_type **prev,
4224130561Sobrien   fill_type *fill,
4225130561Sobrien   bfd_vma dot,
4226130561Sobrien   bfd_boolean *relax,
4227130561Sobrien   bfd_boolean check_regions)
422833965Sjdp{
422960484Sobrien  /* Size up the sections from their constituent parts.  */
4230130561Sobrien  for (; s != NULL; s = s->header.next)
423133965Sjdp    {
423260484Sobrien      switch (s->header.type)
423360484Sobrien	{
423460484Sobrien	case lang_output_section_statement_enum:
423560484Sobrien	  {
4236218822Sdim	    bfd_vma newdot, after;
423778828Sobrien	    lang_output_section_statement_type *os;
4238218822Sdim	    lang_memory_region_type *r;
423933965Sjdp
424078828Sobrien	    os = &s->output_section_statement;
4241218822Sdim	    if (os->addr_tree != NULL)
4242218822Sdim	      {
4243218822Sdim		os->processed_vma = FALSE;
4244218822Sdim		exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot);
4245218822Sdim
4246218822Sdim		if (!expld.result.valid_p
4247218822Sdim		    && expld.phase != lang_mark_phase_enum)
4248218822Sdim		  einfo (_("%F%S: non constant or forward reference"
4249218822Sdim			   " address expression for section %s\n"),
4250218822Sdim			 os->name);
4251218822Sdim
4252218822Sdim		dot = expld.result.value + expld.result.section->vma;
4253218822Sdim	      }
4254218822Sdim
425560484Sobrien	    if (os->bfd_section == NULL)
4256218822Sdim	      /* This section was removed or never actually created.  */
425760484Sobrien	      break;
425833965Sjdp
425960484Sobrien	    /* If this is a COFF shared library section, use the size and
426060484Sobrien	       address from the input section.  FIXME: This is COFF
426160484Sobrien	       specific; it would be cleaner if there were some other way
426260484Sobrien	       to do this, but nothing simple comes to mind.  */
4263218822Sdim	    if ((bfd_get_flavour (output_bfd) == bfd_target_ecoff_flavour
4264218822Sdim		 || bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
4265218822Sdim		&& (os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
426660484Sobrien	      {
426777298Sobrien		asection *input;
426833965Sjdp
426960484Sobrien		if (os->children.head == NULL
427089857Sobrien		    || os->children.head->header.next != NULL
4271218822Sdim		    || (os->children.head->header.type
4272218822Sdim			!= lang_input_section_enum))
4273218822Sdim		  einfo (_("%P%X: Internal error on COFF shared library"
4274218822Sdim			   " section %s\n"), os->name);
427533965Sjdp
427660484Sobrien		input = os->children.head->input_section.section;
4277222206Sbenl		(void) bfd_set_section_vma (os->bfd_section->owner,
4278222206Sbenl					    os->bfd_section,
4279222206Sbenl					    bfd_section_vma (input->owner,
4280222206Sbenl							     input));
4281218822Sdim		os->bfd_section->size = input->size;
428260484Sobrien		break;
428360484Sobrien	      }
428433965Sjdp
4285218822Sdim	    newdot = dot;
428660484Sobrien	    if (bfd_is_abs_section (os->bfd_section))
428760484Sobrien	      {
428860484Sobrien		/* No matter what happens, an abs section starts at zero.  */
428960484Sobrien		ASSERT (os->bfd_section->vma == 0);
429060484Sobrien	      }
429160484Sobrien	    else
429260484Sobrien	      {
4293218822Sdim		int align;
4294218822Sdim
4295130561Sobrien		if (os->addr_tree == NULL)
429660484Sobrien		  {
429760484Sobrien		    /* No address specified for this section, get one
429860484Sobrien		       from the region specification.  */
4299130561Sobrien		    if (os->region == NULL
4300218822Sdim			|| ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))
430160484Sobrien			    && os->region->name[0] == '*'
4302218822Sdim			    && strcmp (os->region->name,
4303218822Sdim				       DEFAULT_MEMORY_REGION) == 0))
430460484Sobrien		      {
430560484Sobrien			os->region = lang_memory_default (os->bfd_section);
430660484Sobrien		      }
430733965Sjdp
430860484Sobrien		    /* If a loadable section is using the default memory
430960484Sobrien		       region, and some non default memory regions were
4310130561Sobrien		       defined, issue an error message.  */
4311218822Sdim		    if (!os->ignored
4312218822Sdim			&& !IGNORE_SECTION (os->bfd_section)
4313130561Sobrien			&& ! link_info.relocatable
4314130561Sobrien			&& check_regions
4315218822Sdim			&& strcmp (os->region->name,
4316218822Sdim				   DEFAULT_MEMORY_REGION) == 0
431760484Sobrien			&& lang_memory_region_list != NULL
431878828Sobrien			&& (strcmp (lang_memory_region_list->name,
4319130561Sobrien				    DEFAULT_MEMORY_REGION) != 0
4320218822Sdim			    || lang_memory_region_list->next != NULL)
4321218822Sdim			&& expld.phase != lang_mark_phase_enum)
4322130561Sobrien		      {
4323130561Sobrien			/* By default this is an error rather than just a
4324130561Sobrien			   warning because if we allocate the section to the
4325130561Sobrien			   default memory region we can end up creating an
4326130561Sobrien			   excessively large binary, or even seg faulting when
4327130561Sobrien			   attempting to perform a negative seek.  See
4328218822Sdim			   sources.redhat.com/ml/binutils/2003-04/msg00423.html
4329130561Sobrien			   for an example of this.  This behaviour can be
4330130561Sobrien			   overridden by the using the --no-check-sections
4331130561Sobrien			   switch.  */
4332130561Sobrien			if (command_line.check_section_addresses)
4333218822Sdim			  einfo (_("%P%F: error: no memory region specified"
4334218822Sdim				   " for loadable section `%s'\n"),
4335130561Sobrien				 bfd_get_section_name (output_bfd,
4336130561Sobrien						       os->bfd_section));
4337130561Sobrien			else
4338218822Sdim			  einfo (_("%P: warning: no memory region specified"
4339218822Sdim				   " for loadable section `%s'\n"),
4340130561Sobrien				 bfd_get_section_name (output_bfd,
4341130561Sobrien						       os->bfd_section));
4342130561Sobrien		      }
434338889Sjdp
4344218822Sdim		    newdot = os->region->current;
4345218822Sdim		    align = os->bfd_section->alignment_power;
434660484Sobrien		  }
434760484Sobrien		else
4348218822Sdim		  align = os->section_alignment;
4349218822Sdim
4350218822Sdim		/* Align to what the section needs.  */
4351218822Sdim		if (align > 0)
435260484Sobrien		  {
4353218822Sdim		    bfd_vma savedot = newdot;
4354218822Sdim		    newdot = align_power (newdot, align);
435533965Sjdp
4356218822Sdim		    if (newdot != savedot
4357218822Sdim			&& (config.warn_section_align
4358218822Sdim			    || os->addr_tree != NULL)
4359218822Sdim			&& expld.phase != lang_mark_phase_enum)
4360218822Sdim		      einfo (_("%P: warning: changing start of section"
4361218822Sdim			       " %s by %lu bytes\n"),
4362218822Sdim			     os->name, (unsigned long) (newdot - savedot));
436360484Sobrien		  }
436477298Sobrien
4365222206Sbenl		(void) bfd_set_section_vma (0, os->bfd_section, newdot);
436633965Sjdp
436760484Sobrien		os->bfd_section->output_offset = 0;
436860484Sobrien	      }
436933965Sjdp
4370104834Sobrien	    lang_size_sections_1 (os->children.head, os, &os->children.head,
4371218822Sdim				  os->fill, newdot, relax, check_regions);
437277298Sobrien
4373218822Sdim	    os->processed_vma = TRUE;
437433965Sjdp
4375218822Sdim	    if (bfd_is_abs_section (os->bfd_section) || os->ignored)
4376218822Sdim	      /* Except for some special linker created sections,
4377218822Sdim		 no output section should change from zero size
4378218822Sdim		 after strip_excluded_output_sections.  A non-zero
4379218822Sdim		 size on an ignored section indicates that some
4380218822Sdim		 input section was not sized early enough.  */
4381218822Sdim	      ASSERT (os->bfd_section->size == 0);
438260484Sobrien	    else
4383218822Sdim	      {
4384218822Sdim		dot = os->bfd_section->vma;
4385104834Sobrien
4386218822Sdim		/* Put the section within the requested block size, or
4387218822Sdim		   align at the block boundary.  */
4388218822Sdim		after = ((dot
4389218822Sdim			  + TO_ADDR (os->bfd_section->size)
4390218822Sdim			  + os->block_value - 1)
4391218822Sdim			 & - (bfd_vma) os->block_value);
4392218822Sdim
4393218822Sdim		os->bfd_section->size = TO_SIZE (after - os->bfd_section->vma);
4394218822Sdim	      }
4395218822Sdim
4396218822Sdim	    /* Set section lma.  */
4397218822Sdim	    r = os->region;
4398218822Sdim	    if (r == NULL)
4399218822Sdim	      r = lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
4400218822Sdim
4401218822Sdim	    if (os->load_base)
4402218822Sdim	      {
4403218822Sdim		bfd_vma lma = exp_get_abs_int (os->load_base, 0, "load base");
4404218822Sdim		os->bfd_section->lma = lma;
4405218822Sdim	      }
4406218822Sdim	    else if (os->region != NULL
4407218822Sdim		     && os->lma_region != NULL
4408218822Sdim		     && os->lma_region != os->region)
4409218822Sdim	      {
4410218822Sdim		bfd_vma lma = os->lma_region->current;
4411218822Sdim
4412218822Sdim		if (os->section_alignment != -1)
4413218822Sdim		  lma = align_power (lma, os->section_alignment);
4414218822Sdim		os->bfd_section->lma = lma;
4415218822Sdim	      }
4416218822Sdim	    else if (r->last_os != NULL
4417218822Sdim		     && (os->bfd_section->flags & SEC_ALLOC) != 0)
4418218822Sdim	      {
4419218822Sdim		bfd_vma lma;
4420218822Sdim		asection *last;
4421218822Sdim
4422218822Sdim		last = r->last_os->output_section_statement.bfd_section;
4423218822Sdim
4424218822Sdim		/* A backwards move of dot should be accompanied by
4425218822Sdim		   an explicit assignment to the section LMA (ie.
4426218822Sdim		   os->load_base set) because backwards moves can
4427218822Sdim		   create overlapping LMAs.  */
4428218822Sdim		if (dot < last->vma
4429218822Sdim		    && os->bfd_section->size != 0
4430218822Sdim		    && dot + os->bfd_section->size <= last->vma)
4431218822Sdim		  {
4432218822Sdim		    /* If dot moved backwards then leave lma equal to
4433218822Sdim		       vma.  This is the old default lma, which might
4434218822Sdim		       just happen to work when the backwards move is
4435218822Sdim		       sufficiently large.  Nag if this changes anything,
4436218822Sdim		       so people can fix their linker scripts.  */
4437218822Sdim
4438218822Sdim		    if (last->vma != last->lma)
4439218822Sdim		      einfo (_("%P: warning: dot moved backwards before `%s'\n"),
4440218822Sdim			     os->name);
4441218822Sdim		  }
4442218822Sdim		else
4443218822Sdim		  {
4444218822Sdim		    /* If this is an overlay, set the current lma to that
4445218822Sdim		       at the end of the previous section.  */
4446218822Sdim		    if (os->sectype == overlay_section)
4447218822Sdim		      lma = last->lma + last->size;
4448218822Sdim
4449218822Sdim		    /* Otherwise, keep the same lma to vma relationship
4450218822Sdim		       as the previous section.  */
4451218822Sdim		    else
4452218822Sdim		      lma = dot + last->lma - last->vma;
4453218822Sdim
4454218822Sdim		    if (os->section_alignment != -1)
4455218822Sdim		      lma = align_power (lma, os->section_alignment);
4456218822Sdim		    os->bfd_section->lma = lma;
4457218822Sdim		  }
4458218822Sdim	      }
4459218822Sdim	    os->processed_lma = TRUE;
4460218822Sdim
4461218822Sdim	    if (bfd_is_abs_section (os->bfd_section) || os->ignored)
4462218822Sdim	      break;
4463218822Sdim
4464218822Sdim	    /* Keep track of normal sections using the default
4465218822Sdim	       lma region.  We use this to set the lma for
4466218822Sdim	       following sections.  Overlays or other linker
4467218822Sdim	       script assignment to lma might mean that the
4468218822Sdim	       default lma == vma is incorrect.
4469218822Sdim	       To avoid warnings about dot moving backwards when using
4470218822Sdim	       -Ttext, don't start tracking sections until we find one
4471218822Sdim	       of non-zero size or with lma set differently to vma.  */
4472218822Sdim	    if (((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
4473218822Sdim		 || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0)
4474218822Sdim		&& (os->bfd_section->flags & SEC_ALLOC) != 0
4475218822Sdim		&& (os->bfd_section->size != 0
4476218822Sdim		    || (r->last_os == NULL
4477218822Sdim			&& os->bfd_section->vma != os->bfd_section->lma)
4478218822Sdim		    || (r->last_os != NULL
4479218822Sdim			&& dot >= (r->last_os->output_section_statement
4480218822Sdim				   .bfd_section->vma)))
4481218822Sdim		&& os->lma_region == NULL
4482218822Sdim		&& !link_info.relocatable)
4483218822Sdim	      r->last_os = s;
4484218822Sdim
4485130561Sobrien	    /* .tbss sections effectively have zero size.  */
4486130561Sobrien	    if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
4487130561Sobrien		|| (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
4488130561Sobrien		|| link_info.relocatable)
4489218822Sdim	      dot += TO_ADDR (os->bfd_section->size);
449033965Sjdp
4491104834Sobrien	    if (os->update_dot_tree != 0)
4492218822Sdim	      exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot);
4493104834Sobrien
449460484Sobrien	    /* Update dot in the region ?
449560484Sobrien	       We only do this if the section is going to be allocated,
449660484Sobrien	       since unallocated sections do not contribute to the region's
449760484Sobrien	       overall size in memory.
449877298Sobrien
449960484Sobrien	       If the SEC_NEVER_LOAD bit is not set, it will affect the
450060484Sobrien	       addresses of sections after it. We have to update
450160484Sobrien	       dot.  */
4502130561Sobrien	    if (os->region != NULL
4503218822Sdim		&& ((os->bfd_section->flags & SEC_NEVER_LOAD) == 0
4504218822Sdim		    || (os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))))
450560484Sobrien	      {
450660484Sobrien		os->region->current = dot;
450777298Sobrien
4508130561Sobrien		if (check_regions)
4509130561Sobrien		  /* Make sure the new address is within the region.  */
4510130561Sobrien		  os_region_check (os, os->region, os->addr_tree,
4511130561Sobrien				   os->bfd_section->vma);
451233965Sjdp
4513104834Sobrien		if (os->lma_region != NULL && os->lma_region != os->region)
451477298Sobrien		  {
4515218822Sdim		    os->lma_region->current
4516218822Sdim		      = os->bfd_section->lma + TO_ADDR (os->bfd_section->size);
4517218822Sdim
4518130561Sobrien		    if (check_regions)
4519130561Sobrien		      os_region_check (os, os->lma_region, NULL,
4520130561Sobrien				       os->bfd_section->lma);
452177298Sobrien		  }
452260484Sobrien	      }
452360484Sobrien	  }
452460484Sobrien	  break;
452533965Sjdp
452660484Sobrien	case lang_constructors_statement_enum:
4527104834Sobrien	  dot = lang_size_sections_1 (constructor_list.head,
4528104834Sobrien				      output_section_statement,
4529104834Sobrien				      &s->wild_statement.children.head,
4530130561Sobrien				      fill, dot, relax, check_regions);
453160484Sobrien	  break;
453233965Sjdp
453360484Sobrien	case lang_data_statement_enum:
453460484Sobrien	  {
453560484Sobrien	    unsigned int size = 0;
453633965Sjdp
4537218822Sdim	    s->data_statement.output_offset =
453877298Sobrien	      dot - output_section_statement->bfd_section->vma;
453960484Sobrien	    s->data_statement.output_section =
454060484Sobrien	      output_section_statement->bfd_section;
454133965Sjdp
4542130561Sobrien	    /* We might refer to provided symbols in the expression, and
4543130561Sobrien	       need to mark them as needed.  */
4544218822Sdim	    exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
4545130561Sobrien
454660484Sobrien	    switch (s->data_statement.type)
454760484Sobrien	      {
454877298Sobrien	      default:
454977298Sobrien		abort ();
455060484Sobrien	      case QUAD:
455160484Sobrien	      case SQUAD:
455260484Sobrien		size = QUAD_SIZE;
455360484Sobrien		break;
455460484Sobrien	      case LONG:
455560484Sobrien		size = LONG_SIZE;
455660484Sobrien		break;
455760484Sobrien	      case SHORT:
455860484Sobrien		size = SHORT_SIZE;
455960484Sobrien		break;
456060484Sobrien	      case BYTE:
456160484Sobrien		size = BYTE_SIZE;
456260484Sobrien		break;
456360484Sobrien	      }
4564130561Sobrien	    if (size < TO_SIZE ((unsigned) 1))
4565130561Sobrien	      size = TO_SIZE ((unsigned) 1);
4566130561Sobrien	    dot += TO_ADDR (size);
4567218822Sdim	    output_section_statement->bfd_section->size += size;
456860484Sobrien	  }
456960484Sobrien	  break;
457033965Sjdp
457160484Sobrien	case lang_reloc_statement_enum:
457260484Sobrien	  {
457360484Sobrien	    int size;
457433965Sjdp
4575218822Sdim	    s->reloc_statement.output_offset =
457660484Sobrien	      dot - output_section_statement->bfd_section->vma;
457760484Sobrien	    s->reloc_statement.output_section =
457860484Sobrien	      output_section_statement->bfd_section;
457960484Sobrien	    size = bfd_get_reloc_size (s->reloc_statement.howto);
4580130561Sobrien	    dot += TO_ADDR (size);
4581218822Sdim	    output_section_statement->bfd_section->size += size;
458260484Sobrien	  }
458360484Sobrien	  break;
458477298Sobrien
458560484Sobrien	case lang_wild_statement_enum:
4586104834Sobrien	  dot = lang_size_sections_1 (s->wild_statement.children.head,
4587104834Sobrien				      output_section_statement,
4588104834Sobrien				      &s->wild_statement.children.head,
4589130561Sobrien				      fill, dot, relax, check_regions);
459060484Sobrien	  break;
459133965Sjdp
459260484Sobrien	case lang_object_symbols_statement_enum:
459360484Sobrien	  link_info.create_object_symbols_section =
459460484Sobrien	    output_section_statement->bfd_section;
459560484Sobrien	  break;
4596218822Sdim
459760484Sobrien	case lang_output_statement_enum:
459860484Sobrien	case lang_target_statement_enum:
459960484Sobrien	  break;
4600218822Sdim
460160484Sobrien	case lang_input_section_enum:
460233965Sjdp	  {
460360484Sobrien	    asection *i;
460433965Sjdp
460560484Sobrien	    i = (*prev)->input_section.section;
4606218822Sdim	    if (relax)
460760484Sobrien	      {
4608130561Sobrien		bfd_boolean again;
460960484Sobrien
461060484Sobrien		if (! bfd_relax_section (i->owner, i, &link_info, &again))
461160484Sobrien		  einfo (_("%P%F: can't relax section: %E\n"));
461260484Sobrien		if (again)
4613130561Sobrien		  *relax = TRUE;
461460484Sobrien	      }
461589857Sobrien	    dot = size_input_section (prev, output_section_statement,
461689857Sobrien				      output_section_statement->fill, dot);
461733965Sjdp	  }
461860484Sobrien	  break;
4619218822Sdim
462060484Sobrien	case lang_input_statement_enum:
462160484Sobrien	  break;
4622218822Sdim
462360484Sobrien	case lang_fill_statement_enum:
462477298Sobrien	  s->fill_statement.output_section =
462577298Sobrien	    output_section_statement->bfd_section;
462633965Sjdp
462760484Sobrien	  fill = s->fill_statement.fill;
462860484Sobrien	  break;
4629218822Sdim
463060484Sobrien	case lang_assignment_statement_enum:
463160484Sobrien	  {
463260484Sobrien	    bfd_vma newdot = dot;
4633218822Sdim	    etree_type *tree = s->assignment_statement.exp;
463433965Sjdp
4635218822Sdim	    exp_fold_tree (tree,
4636218822Sdim			   output_section_statement->bfd_section,
463760484Sobrien			   &newdot);
463833965Sjdp
4639218822Sdim	    /* This symbol is relative to this section.  */
4640218822Sdim	    if ((tree->type.node_class == etree_provided
4641218822Sdim		 || tree->type.node_class == etree_assign)
4642218822Sdim		&& (tree->assign.dst [0] != '.'
4643218822Sdim		    || tree->assign.dst [1] != '\0'))
4644218822Sdim	      output_section_statement->section_relative_symbol = 1;
4645218822Sdim
4646218822Sdim	    if (!output_section_statement->ignored)
464760484Sobrien	      {
464860484Sobrien		if (output_section_statement == abs_output_section)
464960484Sobrien		  {
465060484Sobrien		    /* If we don't have an output section, then just adjust
465160484Sobrien		       the default memory address.  */
4652218822Sdim		    lang_memory_region_lookup (DEFAULT_MEMORY_REGION,
4653218822Sdim					       FALSE)->current = newdot;
465460484Sobrien		  }
4655218822Sdim		else if (newdot != dot)
465660484Sobrien		  {
465789857Sobrien		    /* Insert a pad after this statement.  We can't
465889857Sobrien		       put the pad before when relaxing, in case the
465989857Sobrien		       assignment references dot.  */
4660130561Sobrien		    insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot),
466189857Sobrien				output_section_statement->bfd_section, dot);
466233965Sjdp
466389857Sobrien		    /* Don't neuter the pad below when relaxing.  */
466489857Sobrien		    s = s->header.next;
4665218822Sdim
4666218822Sdim		    /* If dot is advanced, this implies that the section
4667218822Sdim		       should have space allocated to it, unless the
4668218822Sdim		       user has explicitly stated that the section
4669218822Sdim		       should never be loaded.  */
4670218822Sdim		    if (!(output_section_statement->flags
4671218822Sdim			  & (SEC_NEVER_LOAD | SEC_ALLOC)))
4672218822Sdim		      output_section_statement->bfd_section->flags |= SEC_ALLOC;
467360484Sobrien		  }
467460484Sobrien		dot = newdot;
467560484Sobrien	      }
467660484Sobrien	  }
467760484Sobrien	  break;
467833965Sjdp
467960484Sobrien	case lang_padding_statement_enum:
468089857Sobrien	  /* If this is the first time lang_size_sections is called,
468189857Sobrien	     we won't have any padding statements.  If this is the
468289857Sobrien	     second or later passes when relaxing, we should allow
468389857Sobrien	     padding to shrink.  If padding is needed on this pass, it
468489857Sobrien	     will be added back in.  */
468589857Sobrien	  s->padding_statement.size = 0;
468689857Sobrien
468789857Sobrien	  /* Make sure output_offset is valid.  If relaxation shrinks
468889857Sobrien	     the section and this pad isn't needed, it's possible to
468989857Sobrien	     have output_offset larger than the final size of the
469089857Sobrien	     section.  bfd_set_section_contents will complain even for
469189857Sobrien	     a pad size of zero.  */
469289857Sobrien	  s->padding_statement.output_offset
469389857Sobrien	    = dot - output_section_statement->bfd_section->vma;
469460484Sobrien	  break;
469533965Sjdp
469660484Sobrien	case lang_group_statement_enum:
4697104834Sobrien	  dot = lang_size_sections_1 (s->group_statement.children.head,
4698104834Sobrien				      output_section_statement,
4699104834Sobrien				      &s->group_statement.children.head,
4700130561Sobrien				      fill, dot, relax, check_regions);
470160484Sobrien	  break;
470233965Sjdp
470360484Sobrien	default:
470460484Sobrien	  FAIL ();
470560484Sobrien	  break;
470633965Sjdp
470789857Sobrien	  /* We can only get here when relaxing is turned on.  */
470860484Sobrien	case lang_address_statement_enum:
470960484Sobrien	  break;
471060484Sobrien	}
471160484Sobrien      prev = &s->header.next;
471233965Sjdp    }
471333965Sjdp  return dot;
471433965Sjdp}
471533965Sjdp
4716218822Sdim/* Callback routine that is used in _bfd_elf_map_sections_to_segments.
4717218822Sdim   The BFD library has set NEW_SEGMENT to TRUE iff it thinks that
4718218822Sdim   CURRENT_SECTION and PREVIOUS_SECTION ought to be placed into different
4719218822Sdim   segments.  We are allowed an opportunity to override this decision.  */
4720218822Sdim
4721218822Sdimbfd_boolean
4722218822Sdimldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED,
4723218822Sdim				    bfd * abfd ATTRIBUTE_UNUSED,
4724218822Sdim				    asection * current_section,
4725218822Sdim				    asection * previous_section,
4726218822Sdim				    bfd_boolean new_segment)
4727104834Sobrien{
4728218822Sdim  lang_output_section_statement_type * cur;
4729218822Sdim  lang_output_section_statement_type * prev;
4730104834Sobrien
4731218822Sdim  /* The checks below are only necessary when the BFD library has decided
4732218822Sdim     that the two sections ought to be placed into the same segment.  */
4733218822Sdim  if (new_segment)
4734218822Sdim    return TRUE;
4735218822Sdim
4736218822Sdim  /* Paranoia checks.  */
4737218822Sdim  if (current_section == NULL || previous_section == NULL)
4738218822Sdim    return new_segment;
4739218822Sdim
4740218822Sdim  /* Find the memory regions associated with the two sections.
4741218822Sdim     We call lang_output_section_find() here rather than scanning the list
4742218822Sdim     of output sections looking for a matching section pointer because if
4743218822Sdim     we have a large number of sections then a hash lookup is faster.  */
4744218822Sdim  cur  = lang_output_section_find (current_section->name);
4745218822Sdim  prev = lang_output_section_find (previous_section->name);
4746218822Sdim
4747218822Sdim  /* More paranoia.  */
4748218822Sdim  if (cur == NULL || prev == NULL)
4749218822Sdim    return new_segment;
4750218822Sdim
4751218822Sdim  /* If the regions are different then force the sections to live in
4752218822Sdim     different segments.  See the email thread starting at the following
4753218822Sdim     URL for the reasons why this is necessary:
4754218822Sdim     http://sourceware.org/ml/binutils/2007-02/msg00216.html  */
4755218822Sdim  return cur->region != prev->region;
4756218822Sdim}
4757218822Sdim
4758218822Sdimvoid
4759218822Sdimone_lang_size_sections_pass (bfd_boolean *relax, bfd_boolean check_regions)
4760218822Sdim{
4761130561Sobrien  lang_statement_iteration++;
4762218822Sdim  lang_size_sections_1 (statement_list.head, abs_output_section,
4763218822Sdim			&statement_list.head, 0, 0, relax, check_regions);
4764218822Sdim}
4765130561Sobrien
4766218822Sdimvoid
4767218822Sdimlang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
4768218822Sdim{
4769218822Sdim  expld.phase = lang_allocating_phase_enum;
4770218822Sdim  expld.dataseg.phase = exp_dataseg_none;
4771218822Sdim
4772218822Sdim  one_lang_size_sections_pass (relax, check_regions);
4773218822Sdim  if (expld.dataseg.phase == exp_dataseg_end_seen
4774218822Sdim      && link_info.relro && expld.dataseg.relro_end)
4775104834Sobrien    {
4776218822Sdim      /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try
4777218822Sdim	 to put expld.dataseg.relro on a (common) page boundary.  */
4778218822Sdim      bfd_vma old_min_base, relro_end, maxpage;
4779218822Sdim
4780218822Sdim      expld.dataseg.phase = exp_dataseg_relro_adjust;
4781218822Sdim      old_min_base = expld.dataseg.min_base;
4782218822Sdim      maxpage = expld.dataseg.maxpagesize;
4783218822Sdim      expld.dataseg.base += (-expld.dataseg.relro_end
4784218822Sdim			     & (expld.dataseg.pagesize - 1));
4785218822Sdim      /* Compute the expected PT_GNU_RELRO segment end.  */
4786218822Sdim      relro_end = (expld.dataseg.relro_end + expld.dataseg.pagesize - 1)
4787218822Sdim		  & ~(expld.dataseg.pagesize - 1);
4788218822Sdim      if (old_min_base + maxpage < expld.dataseg.base)
4789218822Sdim	{
4790218822Sdim	  expld.dataseg.base -= maxpage;
4791218822Sdim	  relro_end -= maxpage;
4792218822Sdim	}
4793218822Sdim      lang_reset_memory_regions ();
4794218822Sdim      one_lang_size_sections_pass (relax, check_regions);
4795218822Sdim      if (expld.dataseg.relro_end > relro_end)
4796218822Sdim	{
4797218822Sdim	  /* The alignment of sections between DATA_SEGMENT_ALIGN
4798218822Sdim	     and DATA_SEGMENT_RELRO_END caused huge padding to be
4799218822Sdim	     inserted at DATA_SEGMENT_RELRO_END.  Try some other base.  */
4800218822Sdim	  asection *sec;
4801218822Sdim	  unsigned int max_alignment_power = 0;
4802218822Sdim
4803218822Sdim	  /* Find maximum alignment power of sections between
4804218822Sdim	     DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END.  */
4805218822Sdim	  for (sec = output_bfd->sections; sec; sec = sec->next)
4806218822Sdim	    if (sec->vma >= expld.dataseg.base
4807218822Sdim		&& sec->vma < expld.dataseg.relro_end
4808218822Sdim		&& sec->alignment_power > max_alignment_power)
4809218822Sdim	      max_alignment_power = sec->alignment_power;
4810218822Sdim
4811218822Sdim	  if (((bfd_vma) 1 << max_alignment_power) < expld.dataseg.pagesize)
4812218822Sdim	    {
4813218822Sdim	      if (expld.dataseg.base - (1 << max_alignment_power)
4814218822Sdim		  < old_min_base)
4815218822Sdim		expld.dataseg.base += expld.dataseg.pagesize;
4816218822Sdim	      expld.dataseg.base -= (1 << max_alignment_power);
4817218822Sdim	      lang_reset_memory_regions ();
4818218822Sdim	      one_lang_size_sections_pass (relax, check_regions);
4819218822Sdim	    }
4820218822Sdim	}
4821218822Sdim      link_info.relro_start = expld.dataseg.base;
4822218822Sdim      link_info.relro_end = expld.dataseg.relro_end;
4823218822Sdim    }
4824218822Sdim  else if (expld.dataseg.phase == exp_dataseg_end_seen)
4825218822Sdim    {
4826104834Sobrien      /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether
4827104834Sobrien	 a page could be saved in the data segment.  */
4828104834Sobrien      bfd_vma first, last;
4829104834Sobrien
4830218822Sdim      first = -expld.dataseg.base & (expld.dataseg.pagesize - 1);
4831218822Sdim      last = expld.dataseg.end & (expld.dataseg.pagesize - 1);
4832104834Sobrien      if (first && last
4833218822Sdim	  && ((expld.dataseg.base & ~(expld.dataseg.pagesize - 1))
4834218822Sdim	      != (expld.dataseg.end & ~(expld.dataseg.pagesize - 1)))
4835218822Sdim	  && first + last <= expld.dataseg.pagesize)
4836104834Sobrien	{
4837218822Sdim	  expld.dataseg.phase = exp_dataseg_adjust;
4838218822Sdim	  lang_reset_memory_regions ();
4839218822Sdim	  one_lang_size_sections_pass (relax, check_regions);
4840104834Sobrien	}
4841104834Sobrien    }
4842104834Sobrien
4843218822Sdim  expld.phase = lang_final_phase_enum;
4844104834Sobrien}
4845104834Sobrien
4846130561Sobrien/* Worker function for lang_do_assignments.  Recursiveness goes here.  */
4847130561Sobrien
4848130561Sobrienstatic bfd_vma
4849218822Sdimlang_do_assignments_1 (lang_statement_union_type *s,
4850218822Sdim		       lang_output_section_statement_type *current_os,
4851218822Sdim		       fill_type *fill,
4852218822Sdim		       bfd_vma dot)
485333965Sjdp{
4854130561Sobrien  for (; s != NULL; s = s->header.next)
485533965Sjdp    {
485633965Sjdp      switch (s->header.type)
485733965Sjdp	{
485833965Sjdp	case lang_constructors_statement_enum:
4859130561Sobrien	  dot = lang_do_assignments_1 (constructor_list.head,
4860218822Sdim				       current_os, fill, dot);
486133965Sjdp	  break;
486233965Sjdp
486333965Sjdp	case lang_output_section_statement_enum:
486433965Sjdp	  {
486578828Sobrien	    lang_output_section_statement_type *os;
486633965Sjdp
486778828Sobrien	    os = &(s->output_section_statement);
4868218822Sdim	    if (os->bfd_section != NULL && !os->ignored)
486933965Sjdp	      {
487033965Sjdp		dot = os->bfd_section->vma;
4871218822Sdim
4872130561Sobrien		lang_do_assignments_1 (os->children.head, os, os->fill, dot);
487360484Sobrien
4874218822Sdim		/* .tbss sections effectively have zero size.  */
4875218822Sdim		if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
4876218822Sdim		    || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
4877218822Sdim		    || link_info.relocatable)
4878218822Sdim		  dot += TO_ADDR (os->bfd_section->size);
487933965Sjdp	      }
488033965Sjdp	  }
488133965Sjdp	  break;
4882218822Sdim
488333965Sjdp	case lang_wild_statement_enum:
488433965Sjdp
4885130561Sobrien	  dot = lang_do_assignments_1 (s->wild_statement.children.head,
4886218822Sdim				       current_os, fill, dot);
488733965Sjdp	  break;
488833965Sjdp
488933965Sjdp	case lang_object_symbols_statement_enum:
489033965Sjdp	case lang_output_statement_enum:
489133965Sjdp	case lang_target_statement_enum:
489233965Sjdp	  break;
4893218822Sdim
489433965Sjdp	case lang_data_statement_enum:
4895218822Sdim	  exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
4896218822Sdim	  if (expld.result.valid_p)
4897218822Sdim	    s->data_statement.value = (expld.result.value
4898218822Sdim				       + expld.result.section->vma);
4899218822Sdim	  else
4900218822Sdim	    einfo (_("%F%P: invalid data statement\n"));
490133965Sjdp	  {
4902104834Sobrien	    unsigned int size;
490377298Sobrien	    switch (s->data_statement.type)
490477298Sobrien	      {
490577298Sobrien	      default:
490677298Sobrien		abort ();
490777298Sobrien	      case QUAD:
490877298Sobrien	      case SQUAD:
490977298Sobrien		size = QUAD_SIZE;
491077298Sobrien		break;
491177298Sobrien	      case LONG:
491277298Sobrien		size = LONG_SIZE;
491377298Sobrien		break;
491477298Sobrien	      case SHORT:
491577298Sobrien		size = SHORT_SIZE;
491677298Sobrien		break;
491777298Sobrien	      case BYTE:
491877298Sobrien		size = BYTE_SIZE;
491977298Sobrien		break;
492077298Sobrien	      }
4921130561Sobrien	    if (size < TO_SIZE ((unsigned) 1))
4922130561Sobrien	      size = TO_SIZE ((unsigned) 1);
4923130561Sobrien	    dot += TO_ADDR (size);
492477298Sobrien	  }
492533965Sjdp	  break;
492633965Sjdp
492733965Sjdp	case lang_reloc_statement_enum:
4928218822Sdim	  exp_fold_tree (s->reloc_statement.addend_exp,
4929218822Sdim			 bfd_abs_section_ptr, &dot);
4930218822Sdim	  if (expld.result.valid_p)
4931218822Sdim	    s->reloc_statement.addend_value = expld.result.value;
4932218822Sdim	  else
4933218822Sdim	    einfo (_("%F%P: invalid reloc statement\n"));
4934130561Sobrien	  dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto));
493533965Sjdp	  break;
493633965Sjdp
493733965Sjdp	case lang_input_section_enum:
493833965Sjdp	  {
493933965Sjdp	    asection *in = s->input_section.section;
494033965Sjdp
4941218822Sdim	    if ((in->flags & SEC_EXCLUDE) == 0)
4942218822Sdim	      dot += TO_ADDR (in->size);
494333965Sjdp	  }
494433965Sjdp	  break;
494533965Sjdp
494633965Sjdp	case lang_input_statement_enum:
494733965Sjdp	  break;
4948218822Sdim
494933965Sjdp	case lang_fill_statement_enum:
495033965Sjdp	  fill = s->fill_statement.fill;
495133965Sjdp	  break;
4952218822Sdim
495333965Sjdp	case lang_assignment_statement_enum:
4954218822Sdim	  exp_fold_tree (s->assignment_statement.exp,
4955218822Sdim			 current_os->bfd_section,
4956218822Sdim			 &dot);
4957218822Sdim	  break;
495833965Sjdp
495933965Sjdp	case lang_padding_statement_enum:
4960130561Sobrien	  dot += TO_ADDR (s->padding_statement.size);
496133965Sjdp	  break;
496233965Sjdp
496333965Sjdp	case lang_group_statement_enum:
4964130561Sobrien	  dot = lang_do_assignments_1 (s->group_statement.children.head,
4965218822Sdim				       current_os, fill, dot);
496633965Sjdp	  break;
496733965Sjdp
496833965Sjdp	default:
496933965Sjdp	  FAIL ();
497033965Sjdp	  break;
4971218822Sdim
497233965Sjdp	case lang_address_statement_enum:
497333965Sjdp	  break;
497433965Sjdp	}
497533965Sjdp    }
497633965Sjdp  return dot;
497733965Sjdp}
497833965Sjdp
4979130561Sobrienvoid
4980218822Sdimlang_do_assignments (void)
4981130561Sobrien{
4982130561Sobrien  lang_statement_iteration++;
4983218822Sdim  lang_do_assignments_1 (statement_list.head, abs_output_section, NULL, 0);
4984130561Sobrien}
4985130561Sobrien
498633965Sjdp/* Fix any .startof. or .sizeof. symbols.  When the assemblers see the
498733965Sjdp   operator .startof. (section_name), it produces an undefined symbol
498833965Sjdp   .startof.section_name.  Similarly, when it sees
498933965Sjdp   .sizeof. (section_name), it produces an undefined symbol
499033965Sjdp   .sizeof.section_name.  For all the output sections, we look for
499133965Sjdp   such symbols, and set them to the correct value.  */
499233965Sjdp
499333965Sjdpstatic void
4994130561Sobrienlang_set_startof (void)
499533965Sjdp{
499633965Sjdp  asection *s;
499733965Sjdp
4998130561Sobrien  if (link_info.relocatable)
499933965Sjdp    return;
500033965Sjdp
500133965Sjdp  for (s = output_bfd->sections; s != NULL; s = s->next)
500233965Sjdp    {
500333965Sjdp      const char *secname;
500433965Sjdp      char *buf;
500533965Sjdp      struct bfd_link_hash_entry *h;
500633965Sjdp
500733965Sjdp      secname = bfd_get_section_name (output_bfd, s);
500833965Sjdp      buf = xmalloc (10 + strlen (secname));
500933965Sjdp
501033965Sjdp      sprintf (buf, ".startof.%s", secname);
5011130561Sobrien      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
501233965Sjdp      if (h != NULL && h->type == bfd_link_hash_undefined)
501333965Sjdp	{
501433965Sjdp	  h->type = bfd_link_hash_defined;
501533965Sjdp	  h->u.def.value = bfd_get_section_vma (output_bfd, s);
501633965Sjdp	  h->u.def.section = bfd_abs_section_ptr;
501733965Sjdp	}
501833965Sjdp
501933965Sjdp      sprintf (buf, ".sizeof.%s", secname);
5020130561Sobrien      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
502133965Sjdp      if (h != NULL && h->type == bfd_link_hash_undefined)
502233965Sjdp	{
502333965Sjdp	  h->type = bfd_link_hash_defined;
5024218822Sdim	  h->u.def.value = TO_ADDR (s->size);
502533965Sjdp	  h->u.def.section = bfd_abs_section_ptr;
502633965Sjdp	}
502733965Sjdp
502833965Sjdp      free (buf);
502933965Sjdp    }
503033965Sjdp}
503133965Sjdp
503233965Sjdpstatic void
5033218822Sdimlang_end (void)
503433965Sjdp{
503533965Sjdp  struct bfd_link_hash_entry *h;
5036130561Sobrien  bfd_boolean warn;
503733965Sjdp
5038130561Sobrien  if (link_info.relocatable || link_info.shared)
5039130561Sobrien    warn = FALSE;
504033965Sjdp  else
5041130561Sobrien    warn = TRUE;
504233965Sjdp
5043130561Sobrien  if (entry_symbol.name == NULL)
504433965Sjdp    {
5045218822Sdim      /* No entry has been specified.  Look for the default entry, but
5046218822Sdim	 don't warn if we don't find it.  */
5047218822Sdim      entry_symbol.name = entry_symbol_default;
5048130561Sobrien      warn = FALSE;
504933965Sjdp    }
505033965Sjdp
5051104834Sobrien  h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
5052130561Sobrien			    FALSE, FALSE, TRUE);
5053130561Sobrien  if (h != NULL
505433965Sjdp      && (h->type == bfd_link_hash_defined
505533965Sjdp	  || h->type == bfd_link_hash_defweak)
505633965Sjdp      && h->u.def.section->output_section != NULL)
505733965Sjdp    {
505833965Sjdp      bfd_vma val;
505933965Sjdp
506033965Sjdp      val = (h->u.def.value
506133965Sjdp	     + bfd_get_section_vma (output_bfd,
506233965Sjdp				    h->u.def.section->output_section)
506333965Sjdp	     + h->u.def.section->output_offset);
506433965Sjdp      if (! bfd_set_start_address (output_bfd, val))
5065104834Sobrien	einfo (_("%P%F:%s: can't set start address\n"), entry_symbol.name);
506633965Sjdp    }
506733965Sjdp  else
506833965Sjdp    {
506960484Sobrien      bfd_vma val;
507077298Sobrien      const char *send;
507133965Sjdp
507260484Sobrien      /* We couldn't find the entry symbol.  Try parsing it as a
5073218822Sdim	 number.  */
5074104834Sobrien      val = bfd_scan_vma (entry_symbol.name, &send, 0);
507560484Sobrien      if (*send == '\0')
507633965Sjdp	{
507760484Sobrien	  if (! bfd_set_start_address (output_bfd, val))
507860484Sobrien	    einfo (_("%P%F: can't set start address\n"));
507933965Sjdp	}
508033965Sjdp      else
508133965Sjdp	{
508260484Sobrien	  asection *ts;
508360484Sobrien
508460484Sobrien	  /* Can't find the entry symbol, and it's not a number.  Use
508560484Sobrien	     the first address in the text section.  */
508691041Sobrien	  ts = bfd_get_section_by_name (output_bfd, entry_section);
5087130561Sobrien	  if (ts != NULL)
508860484Sobrien	    {
508960484Sobrien	      if (warn)
5090218822Sdim		einfo (_("%P: warning: cannot find entry symbol %s;"
5091218822Sdim			 " defaulting to %V\n"),
5092104834Sobrien		       entry_symbol.name,
5093104834Sobrien		       bfd_get_section_vma (output_bfd, ts));
509460484Sobrien	      if (! bfd_set_start_address (output_bfd,
509560484Sobrien					   bfd_get_section_vma (output_bfd,
509660484Sobrien								ts)))
509760484Sobrien		einfo (_("%P%F: can't set start address\n"));
509860484Sobrien	    }
509960484Sobrien	  else
510060484Sobrien	    {
510160484Sobrien	      if (warn)
5102218822Sdim		einfo (_("%P: warning: cannot find entry symbol %s;"
5103218822Sdim			 " not setting start address\n"),
5104104834Sobrien		       entry_symbol.name);
510560484Sobrien	    }
510633965Sjdp	}
510733965Sjdp    }
5108130561Sobrien
5109218822Sdim  /* Don't bfd_hash_table_free (&lang_definedness_table);
5110218822Sdim     map file output may result in a call of lang_track_definedness.  */
511133965Sjdp}
511233965Sjdp
511338889Sjdp/* This is a small function used when we want to ignore errors from
511438889Sjdp   BFD.  */
511538889Sjdp
511638889Sjdpstatic void
511760484Sobrienignore_bfd_errors (const char *s ATTRIBUTE_UNUSED, ...)
511838889Sjdp{
511938889Sjdp  /* Don't do anything.  */
512038889Sjdp}
512138889Sjdp
512233965Sjdp/* Check that the architecture of all the input files is compatible
512333965Sjdp   with the output file.  Also call the backend to let it do any
512433965Sjdp   other checking that is needed.  */
512533965Sjdp
512633965Sjdpstatic void
5127130561Sobrienlang_check (void)
512833965Sjdp{
512933965Sjdp  lang_statement_union_type *file;
513033965Sjdp  bfd *input_bfd;
513177298Sobrien  const bfd_arch_info_type *compatible;
513233965Sjdp
5133130561Sobrien  for (file = file_chain.head; file != NULL; file = file->input_statement.next)
513433965Sjdp    {
513533965Sjdp      input_bfd = file->input_statement.the_bfd;
5136218822Sdim      compatible
5137218822Sdim	= bfd_arch_get_compatible (input_bfd, output_bfd,
5138218822Sdim				   command_line.accept_unknown_input_arch);
513994536Sobrien
514094536Sobrien      /* In general it is not possible to perform a relocatable
514194536Sobrien	 link between differing object formats when the input
514294536Sobrien	 file has relocations, because the relocations in the
514394536Sobrien	 input format may not have equivalent representations in
514494536Sobrien	 the output format (and besides BFD does not translate
514594536Sobrien	 relocs for other link purposes than a final link).  */
5146130561Sobrien      if ((link_info.relocatable || link_info.emitrelocations)
514794536Sobrien	  && (compatible == NULL
514894536Sobrien	      || bfd_get_flavour (input_bfd) != bfd_get_flavour (output_bfd))
514994536Sobrien	  && (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0)
515094536Sobrien	{
5151218822Sdim	  einfo (_("%P%F: Relocatable linking with relocations from"
5152218822Sdim		   " format %s (%B) to format %s (%B) is not supported\n"),
515394536Sobrien		 bfd_get_target (input_bfd), input_bfd,
515494536Sobrien		 bfd_get_target (output_bfd), output_bfd);
515594536Sobrien	  /* einfo with %F exits.  */
515694536Sobrien	}
515794536Sobrien
515833965Sjdp      if (compatible == NULL)
515938889Sjdp	{
516038889Sjdp	  if (command_line.warn_mismatch)
5161218822Sdim	    einfo (_("%P%X: %s architecture of input file `%B'"
5162218822Sdim		     " is incompatible with %s output\n"),
516338889Sjdp		   bfd_printable_name (input_bfd), input_bfd,
516438889Sjdp		   bfd_printable_name (output_bfd));
516538889Sjdp	}
516677298Sobrien      else if (bfd_count_sections (input_bfd))
516738889Sjdp	{
516877298Sobrien	  /* If the input bfd has no contents, it shouldn't set the
5169104834Sobrien	     private data of the output bfd.  */
517077298Sobrien
517138889Sjdp	  bfd_error_handler_type pfn = NULL;
517233965Sjdp
517338889Sjdp	  /* If we aren't supposed to warn about mismatched input
5174218822Sdim	     files, temporarily set the BFD error handler to a
5175218822Sdim	     function which will do nothing.  We still want to call
5176218822Sdim	     bfd_merge_private_bfd_data, since it may set up
5177218822Sdim	     information which is needed in the output file.  */
517838889Sjdp	  if (! command_line.warn_mismatch)
517938889Sjdp	    pfn = bfd_set_error_handler (ignore_bfd_errors);
518038889Sjdp	  if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
518138889Sjdp	    {
518238889Sjdp	      if (command_line.warn_mismatch)
5183218822Sdim		einfo (_("%P%X: failed to merge target specific data"
5184218822Sdim			 " of file %B\n"), input_bfd);
518538889Sjdp	    }
518638889Sjdp	  if (! command_line.warn_mismatch)
518738889Sjdp	    bfd_set_error_handler (pfn);
518838889Sjdp	}
518933965Sjdp    }
519033965Sjdp}
519133965Sjdp
519233965Sjdp/* Look through all the global common symbols and attach them to the
519333965Sjdp   correct section.  The -sort-common command line switch may be used
519433965Sjdp   to roughly sort the entries by size.  */
519533965Sjdp
519633965Sjdpstatic void
5197130561Sobrienlang_common (void)
519833965Sjdp{
519989857Sobrien  if (command_line.inhibit_common_definition)
520089857Sobrien    return;
5201130561Sobrien  if (link_info.relocatable
520233965Sjdp      && ! command_line.force_common_definition)
520333965Sjdp    return;
520433965Sjdp
520533965Sjdp  if (! config.sort_common)
5206130561Sobrien    bfd_link_hash_traverse (link_info.hash, lang_one_common, NULL);
520733965Sjdp  else
520833965Sjdp    {
520933965Sjdp      int power;
521033965Sjdp
521133965Sjdp      for (power = 4; power >= 0; power--)
5212130561Sobrien	bfd_link_hash_traverse (link_info.hash, lang_one_common, &power);
521333965Sjdp    }
521433965Sjdp}
521533965Sjdp
521633965Sjdp/* Place one common symbol in the correct section.  */
521733965Sjdp
5218130561Sobrienstatic bfd_boolean
5219130561Sobrienlang_one_common (struct bfd_link_hash_entry *h, void *info)
522033965Sjdp{
522133965Sjdp  unsigned int power_of_two;
522233965Sjdp  bfd_vma size;
522333965Sjdp  asection *section;
522433965Sjdp
522533965Sjdp  if (h->type != bfd_link_hash_common)
5226130561Sobrien    return TRUE;
522733965Sjdp
522833965Sjdp  size = h->u.c.size;
522933965Sjdp  power_of_two = h->u.c.p->alignment_power;
523033965Sjdp
523133965Sjdp  if (config.sort_common
523233965Sjdp      && power_of_two < (unsigned int) *(int *) info)
5233130561Sobrien    return TRUE;
523433965Sjdp
523533965Sjdp  section = h->u.c.p->section;
523633965Sjdp
5237130561Sobrien  /* Increase the size of the section to align the common sym.  */
5238218822Sdim  section->size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1;
5239218822Sdim  section->size &= (- (bfd_vma) 1 << (power_of_two + opb_shift));
524033965Sjdp
524133965Sjdp  /* Adjust the alignment if necessary.  */
524233965Sjdp  if (power_of_two > section->alignment_power)
524333965Sjdp    section->alignment_power = power_of_two;
524433965Sjdp
524533965Sjdp  /* Change the symbol from common to defined.  */
524633965Sjdp  h->type = bfd_link_hash_defined;
524733965Sjdp  h->u.def.section = section;
5248218822Sdim  h->u.def.value = section->size;
524933965Sjdp
525033965Sjdp  /* Increase the size of the section.  */
5251218822Sdim  section->size += size;
525233965Sjdp
525333965Sjdp  /* Make sure the section is allocated in memory, and make sure that
525433965Sjdp     it is no longer a common section.  */
525533965Sjdp  section->flags |= SEC_ALLOC;
525677298Sobrien  section->flags &= ~SEC_IS_COMMON;
525733965Sjdp
525833965Sjdp  if (config.map_file != NULL)
525933965Sjdp    {
5260130561Sobrien      static bfd_boolean header_printed;
526133965Sjdp      int len;
526233965Sjdp      char *name;
526333965Sjdp      char buf[50];
526433965Sjdp
526533965Sjdp      if (! header_printed)
526633965Sjdp	{
526760484Sobrien	  minfo (_("\nAllocating common symbols\n"));
526860484Sobrien	  minfo (_("Common symbol       size              file\n\n"));
5269130561Sobrien	  header_printed = TRUE;
527033965Sjdp	}
527133965Sjdp
5272218822Sdim      name = bfd_demangle (output_bfd, h->root.string,
5273218822Sdim			   DMGL_ANSI | DMGL_PARAMS);
5274218822Sdim      if (name == NULL)
5275218822Sdim	{
5276218822Sdim	  minfo ("%s", h->root.string);
5277218822Sdim	  len = strlen (h->root.string);
5278218822Sdim	}
5279218822Sdim      else
5280218822Sdim	{
5281218822Sdim	  minfo ("%s", name);
5282218822Sdim	  len = strlen (name);
5283218822Sdim	  free (name);
5284218822Sdim	}
528533965Sjdp
528633965Sjdp      if (len >= 19)
528733965Sjdp	{
528833965Sjdp	  print_nl ();
528933965Sjdp	  len = 0;
529033965Sjdp	}
529133965Sjdp      while (len < 20)
529233965Sjdp	{
529333965Sjdp	  print_space ();
529433965Sjdp	  ++len;
529533965Sjdp	}
529633965Sjdp
529733965Sjdp      minfo ("0x");
529833965Sjdp      if (size <= 0xffffffff)
529933965Sjdp	sprintf (buf, "%lx", (unsigned long) size);
530033965Sjdp      else
530133965Sjdp	sprintf_vma (buf, size);
530233965Sjdp      minfo ("%s", buf);
530333965Sjdp      len = strlen (buf);
530433965Sjdp
530533965Sjdp      while (len < 16)
530633965Sjdp	{
530733965Sjdp	  print_space ();
530833965Sjdp	  ++len;
530933965Sjdp	}
531033965Sjdp
531133965Sjdp      minfo ("%B\n", section->owner);
531233965Sjdp    }
531333965Sjdp
5314130561Sobrien  return TRUE;
531533965Sjdp}
531633965Sjdp
531777298Sobrien/* Run through the input files and ensure that every input section has
531877298Sobrien   somewhere to go.  If one is found without a destination then create
531977298Sobrien   an input request and place it into the statement tree.  */
532033965Sjdp
532133965Sjdpstatic void
5322130561Sobrienlang_place_orphans (void)
532333965Sjdp{
532460484Sobrien  LANG_FOR_EACH_INPUT_STATEMENT (file)
532533965Sjdp    {
532633965Sjdp      asection *s;
532733965Sjdp
5328130561Sobrien      for (s = file->the_bfd->sections; s != NULL; s = s->next)
532933965Sjdp	{
5330130561Sobrien	  if (s->output_section == NULL)
533133965Sjdp	    {
5332130561Sobrien	      /* This section of the file is not attached, root
5333218822Sdim		 around for a sensible place for it to go.  */
533433965Sjdp
533533965Sjdp	      if (file->just_syms_flag)
5336218822Sdim		bfd_link_just_syms (file->the_bfd, s, &link_info);
5337218822Sdim	      else if ((s->flags & SEC_EXCLUDE) != 0)
5338218822Sdim		s->output_section = bfd_abs_section_ptr;
533933965Sjdp	      else if (strcmp (s->name, "COMMON") == 0)
534033965Sjdp		{
534133965Sjdp		  /* This is a lonely common section which must have
534233965Sjdp		     come from an archive.  We attach to the section
534333965Sjdp		     with the wildcard.  */
5344130561Sobrien		  if (! link_info.relocatable
534533965Sjdp		      || command_line.force_common_definition)
534633965Sjdp		    {
534733965Sjdp		      if (default_common_section == NULL)
534833965Sjdp			{
534933965Sjdp			  default_common_section =
535033965Sjdp			    lang_output_section_statement_lookup (".bss");
535133965Sjdp
535233965Sjdp			}
535389857Sobrien		      lang_add_section (&default_common_section->children, s,
5354218822Sdim					default_common_section);
535533965Sjdp		    }
535633965Sjdp		}
5357218822Sdim	      else if (ldemul_place_orphan (s))
535833965Sjdp		;
535933965Sjdp	      else
536033965Sjdp		{
536189857Sobrien		  lang_output_section_statement_type *os;
536233965Sjdp
536389857Sobrien		  os = lang_output_section_statement_lookup (s->name);
5364218822Sdim		  lang_add_section (&os->children, s, os);
536533965Sjdp		}
536633965Sjdp	    }
536733965Sjdp	}
536833965Sjdp    }
536933965Sjdp}
537033965Sjdp
537133965Sjdpvoid
5372130561Sobrienlang_set_flags (lang_memory_region_type *ptr, const char *flags, int invert)
537333965Sjdp{
537460484Sobrien  flagword *ptr_flags;
537533965Sjdp
537660484Sobrien  ptr_flags = invert ? &ptr->not_flags : &ptr->flags;
537733965Sjdp  while (*flags)
537833965Sjdp    {
537933965Sjdp      switch (*flags)
538033965Sjdp	{
538138889Sjdp	case 'A': case 'a':
538238889Sjdp	  *ptr_flags |= SEC_ALLOC;
538333965Sjdp	  break;
538438889Sjdp
538538889Sjdp	case 'R': case 'r':
538638889Sjdp	  *ptr_flags |= SEC_READONLY;
538733965Sjdp	  break;
538838889Sjdp
538938889Sjdp	case 'W': case 'w':
539038889Sjdp	  *ptr_flags |= SEC_DATA;
539133965Sjdp	  break;
539238889Sjdp
539338889Sjdp	case 'X': case 'x':
539438889Sjdp	  *ptr_flags |= SEC_CODE;
539538889Sjdp	  break;
539638889Sjdp
539738889Sjdp	case 'L': case 'l':
539838889Sjdp	case 'I': case 'i':
539938889Sjdp	  *ptr_flags |= SEC_LOAD;
540038889Sjdp	  break;
540138889Sjdp
540233965Sjdp	default:
540360484Sobrien	  einfo (_("%P%F: invalid syntax in flags\n"));
540433965Sjdp	  break;
540533965Sjdp	}
540633965Sjdp      flags++;
540733965Sjdp    }
540833965Sjdp}
540933965Sjdp
541033965Sjdp/* Call a function on each input file.  This function will be called
541133965Sjdp   on an archive, but not on the elements.  */
541233965Sjdp
541333965Sjdpvoid
5414130561Sobrienlang_for_each_input_file (void (*func) (lang_input_statement_type *))
541533965Sjdp{
541633965Sjdp  lang_input_statement_type *f;
541733965Sjdp
541833965Sjdp  for (f = (lang_input_statement_type *) input_file_chain.head;
541933965Sjdp       f != NULL;
542033965Sjdp       f = (lang_input_statement_type *) f->next_real_file)
542133965Sjdp    func (f);
542233965Sjdp}
542333965Sjdp
542433965Sjdp/* Call a function on each file.  The function will be called on all
542533965Sjdp   the elements of an archive which are included in the link, but will
542633965Sjdp   not be called on the archive file itself.  */
542733965Sjdp
542833965Sjdpvoid
5429130561Sobrienlang_for_each_file (void (*func) (lang_input_statement_type *))
543033965Sjdp{
543160484Sobrien  LANG_FOR_EACH_INPUT_STATEMENT (f)
543233965Sjdp    {
543333965Sjdp      func (f);
543433965Sjdp    }
543533965Sjdp}
543633965Sjdp
543733965Sjdpvoid
5438130561Sobrienldlang_add_file (lang_input_statement_type *entry)
543933965Sjdp{
544033965Sjdp  lang_statement_append (&file_chain,
544133965Sjdp			 (lang_statement_union_type *) entry,
544233965Sjdp			 &entry->next);
544333965Sjdp
544433965Sjdp  /* The BFD linker needs to have a list of all input BFDs involved in
544533965Sjdp     a link.  */
5446130561Sobrien  ASSERT (entry->the_bfd->link_next == NULL);
544733965Sjdp  ASSERT (entry->the_bfd != output_bfd);
5448218822Sdim
5449218822Sdim  *link_info.input_bfds_tail = entry->the_bfd;
5450218822Sdim  link_info.input_bfds_tail = &entry->the_bfd->link_next;
5451130561Sobrien  entry->the_bfd->usrdata = entry;
545233965Sjdp  bfd_set_gp_size (entry->the_bfd, g_switch_value);
545333965Sjdp
545433965Sjdp  /* Look through the sections and check for any which should not be
545533965Sjdp     included in the link.  We need to do this now, so that we can
545633965Sjdp     notice when the backend linker tries to report multiple
545733965Sjdp     definition errors for symbols which are in sections we aren't
545833965Sjdp     going to link.  FIXME: It might be better to entirely ignore
545933965Sjdp     symbols which are defined in sections which are going to be
546033965Sjdp     discarded.  This would require modifying the backend linker for
546133965Sjdp     each backend which might set the SEC_LINK_ONCE flag.  If we do
546233965Sjdp     this, we should probably handle SEC_EXCLUDE in the same way.  */
546333965Sjdp
5464130561Sobrien  bfd_map_over_sections (entry->the_bfd, section_already_linked, entry);
546533965Sjdp}
546633965Sjdp
546733965Sjdpvoid
5468130561Sobrienlang_add_output (const char *name, int from_script)
546933965Sjdp{
547033965Sjdp  /* Make -o on command line override OUTPUT in script.  */
5471107492Sobrien  if (!had_output_filename || !from_script)
547233965Sjdp    {
547333965Sjdp      output_filename = name;
5474130561Sobrien      had_output_filename = TRUE;
547533965Sjdp    }
547633965Sjdp}
547733965Sjdp
547833965Sjdpstatic lang_output_section_statement_type *current_section;
547933965Sjdp
548033965Sjdpstatic int
5481130561Sobrientopower (int x)
548233965Sjdp{
548333965Sjdp  unsigned int i = 1;
548433965Sjdp  int l;
548533965Sjdp
548633965Sjdp  if (x < 0)
548733965Sjdp    return -1;
548833965Sjdp
548977298Sobrien  for (l = 0; l < 32; l++)
549033965Sjdp    {
549133965Sjdp      if (i >= (unsigned int) x)
549233965Sjdp	return l;
549333965Sjdp      i <<= 1;
549433965Sjdp    }
549533965Sjdp
549633965Sjdp  return 0;
549733965Sjdp}
549833965Sjdp
549968765Sobrienlang_output_section_statement_type *
5500130561Sobrienlang_enter_output_section_statement (const char *output_section_statement_name,
5501130561Sobrien				     etree_type *address_exp,
5502130561Sobrien				     enum section_type sectype,
5503130561Sobrien				     etree_type *align,
5504130561Sobrien				     etree_type *subalign,
5505218822Sdim				     etree_type *ebase,
5506218822Sdim				     int constraint)
550733965Sjdp{
550833965Sjdp  lang_output_section_statement_type *os;
550933965Sjdp
5510218822Sdim   os = lang_output_section_statement_lookup_1 (output_section_statement_name,
5511218822Sdim						constraint);
5512218822Sdim   current_section = os;
551333965Sjdp
551477298Sobrien  /* Make next things chain into subchain of this.  */
551533965Sjdp
5516130561Sobrien  if (os->addr_tree == NULL)
551777298Sobrien    {
551877298Sobrien      os->addr_tree = address_exp;
551977298Sobrien    }
552033965Sjdp  os->sectype = sectype;
552133965Sjdp  if (sectype != noload_section)
552233965Sjdp    os->flags = SEC_NO_FLAGS;
552333965Sjdp  else
552433965Sjdp    os->flags = SEC_NEVER_LOAD;
5525130561Sobrien  os->block_value = 1;
552633965Sjdp  stat_ptr = &os->children;
552733965Sjdp
552877298Sobrien  os->subsection_alignment =
5529218822Sdim    topower (exp_get_value_int (subalign, -1, "subsection alignment"));
553077298Sobrien  os->section_alignment =
5531218822Sdim    topower (exp_get_value_int (align, -1, "section alignment"));
553233965Sjdp
553333965Sjdp  os->load_base = ebase;
553468765Sobrien  return os;
553533965Sjdp}
553633965Sjdp
553733965Sjdpvoid
5538130561Sobrienlang_final (void)
553933965Sjdp{
5540218822Sdim  lang_output_statement_type *new;
554133965Sjdp
5542218822Sdim  new = new_stat (lang_output_statement, stat_ptr);
554333965Sjdp  new->name = output_filename;
554433965Sjdp}
554533965Sjdp
554677298Sobrien/* Reset the current counters in the regions.  */
554777298Sobrien
554891041Sobrienvoid
5549130561Sobrienlang_reset_memory_regions (void)
555033965Sjdp{
555133965Sjdp  lang_memory_region_type *p = lang_memory_region_list;
555289857Sobrien  asection *o;
5553218822Sdim  lang_output_section_statement_type *os;
555433965Sjdp
5555130561Sobrien  for (p = lang_memory_region_list; p != NULL; p = p->next)
555633965Sjdp    {
555733965Sjdp      p->current = p->origin;
5558218822Sdim      p->last_os = NULL;
555933965Sjdp    }
556089857Sobrien
5561218822Sdim  for (os = &lang_output_section_statement.head->output_section_statement;
5562218822Sdim       os != NULL;
5563218822Sdim       os = os->next)
5564218822Sdim    {
5565218822Sdim      os->processed_vma = FALSE;
5566218822Sdim      os->processed_lma = FALSE;
5567218822Sdim    }
5568218822Sdim
556989857Sobrien  for (o = output_bfd->sections; o != NULL; o = o->next)
5570218822Sdim    {
5571218822Sdim      /* Save the last size for possible use by bfd_relax_section.  */
5572218822Sdim      o->rawsize = o->size;
5573218822Sdim      o->size = 0;
5574218822Sdim    }
557533965Sjdp}
557633965Sjdp
5577218822Sdim/* Worker for lang_gc_sections_1.  */
557860484Sobrien
557960484Sobrienstatic void
5580130561Sobriengc_section_callback (lang_wild_statement_type *ptr,
5581130561Sobrien		     struct wildcard_list *sec ATTRIBUTE_UNUSED,
5582130561Sobrien		     asection *section,
5583130561Sobrien		     lang_input_statement_type *file ATTRIBUTE_UNUSED,
5584130561Sobrien		     void *data ATTRIBUTE_UNUSED)
558560484Sobrien{
5586218822Sdim  /* If the wild pattern was marked KEEP, the member sections
5587218822Sdim     should be as well.  */
558860484Sobrien  if (ptr->keep_sections)
558960484Sobrien    section->flags |= SEC_KEEP;
559060484Sobrien}
559160484Sobrien
559260484Sobrien/* Iterate over sections marking them against GC.  */
559360484Sobrien
559460484Sobrienstatic void
5595130561Sobrienlang_gc_sections_1 (lang_statement_union_type *s)
559660484Sobrien{
5597130561Sobrien  for (; s != NULL; s = s->header.next)
559860484Sobrien    {
559960484Sobrien      switch (s->header.type)
560060484Sobrien	{
560160484Sobrien	case lang_wild_statement_enum:
5602218822Sdim	  walk_wild (&s->wild_statement, gc_section_callback, NULL);
560360484Sobrien	  break;
560460484Sobrien	case lang_constructors_statement_enum:
560560484Sobrien	  lang_gc_sections_1 (constructor_list.head);
560660484Sobrien	  break;
560760484Sobrien	case lang_output_section_statement_enum:
560860484Sobrien	  lang_gc_sections_1 (s->output_section_statement.children.head);
560960484Sobrien	  break;
561060484Sobrien	case lang_group_statement_enum:
561160484Sobrien	  lang_gc_sections_1 (s->group_statement.children.head);
561260484Sobrien	  break;
561360484Sobrien	default:
561460484Sobrien	  break;
561560484Sobrien	}
561660484Sobrien    }
561760484Sobrien}
561860484Sobrien
561960484Sobrienstatic void
5620130561Sobrienlang_gc_sections (void)
562160484Sobrien{
562260484Sobrien  struct bfd_link_hash_entry *h;
5623104834Sobrien  ldlang_undef_chain_list_type *ulist;
562460484Sobrien
562560484Sobrien  /* Keep all sections so marked in the link script.  */
562660484Sobrien
562760484Sobrien  lang_gc_sections_1 (statement_list.head);
562860484Sobrien
5629104834Sobrien  /* Keep all sections containing symbols undefined on the command-line,
5630104834Sobrien     and the section containing the entry symbol.  */
563177298Sobrien
5632104834Sobrien  for (ulist = link_info.gc_sym_list; ulist; ulist = ulist->next)
563360484Sobrien    {
563477298Sobrien      h = bfd_link_hash_lookup (link_info.hash, ulist->name,
5635130561Sobrien				FALSE, FALSE, FALSE);
563660484Sobrien
5637130561Sobrien      if (h != NULL
563877298Sobrien	  && (h->type == bfd_link_hash_defined
563977298Sobrien	      || h->type == bfd_link_hash_defweak)
564060484Sobrien	  && ! bfd_is_abs_section (h->u.def.section))
564160484Sobrien	{
564260484Sobrien	  h->u.def.section->flags |= SEC_KEEP;
564360484Sobrien	}
564460484Sobrien    }
564560484Sobrien
5646218822Sdim  /* SEC_EXCLUDE is ignored when doing a relocatable link, except in
5647218822Sdim     the special case of debug info.  (See bfd/stabs.c)
5648218822Sdim     Twiddle the flag here, to simplify later linker code.  */
5649218822Sdim  if (link_info.relocatable)
5650218822Sdim    {
5651218822Sdim      LANG_FOR_EACH_INPUT_STATEMENT (f)
5652218822Sdim	{
5653218822Sdim	  asection *sec;
5654218822Sdim	  for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next)
5655218822Sdim	    if ((sec->flags & SEC_DEBUGGING) == 0)
5656218822Sdim	      sec->flags &= ~SEC_EXCLUDE;
5657218822Sdim	}
5658218822Sdim    }
5659218822Sdim
5660218822Sdim  if (link_info.gc_sections)
5661218822Sdim    bfd_gc_sections (output_bfd, &link_info);
566260484Sobrien}
566360484Sobrien
5664218822Sdim/* Relax all sections until bfd_relax_section gives up.  */
5665218822Sdim
5666218822Sdimstatic void
5667218822Sdimrelax_sections (void)
5668218822Sdim{
5669218822Sdim  /* Keep relaxing until bfd_relax_section gives up.  */
5670218822Sdim  bfd_boolean relax_again;
5671218822Sdim
5672218822Sdim  link_info.relax_trip = -1;
5673218822Sdim  do
5674218822Sdim    {
5675218822Sdim      relax_again = FALSE;
5676218822Sdim      link_info.relax_trip++;
5677218822Sdim
5678218822Sdim      /* Note: pe-dll.c does something like this also.  If you find
5679218822Sdim	 you need to change this code, you probably need to change
5680218822Sdim	 pe-dll.c also.  DJ  */
5681218822Sdim
5682218822Sdim      /* Do all the assignments with our current guesses as to
5683218822Sdim	 section sizes.  */
5684218822Sdim      lang_do_assignments ();
5685218822Sdim
5686218822Sdim      /* We must do this after lang_do_assignments, because it uses
5687218822Sdim	 size.  */
5688218822Sdim      lang_reset_memory_regions ();
5689218822Sdim
5690218822Sdim      /* Perform another relax pass - this time we know where the
5691218822Sdim	 globals are, so can make a better guess.  */
5692218822Sdim      lang_size_sections (&relax_again, FALSE);
5693218822Sdim    }
5694218822Sdim  while (relax_again);
5695218822Sdim}
5696218822Sdim
569733965Sjdpvoid
5698130561Sobrienlang_process (void)
569933965Sjdp{
5700218822Sdim  /* Finalize dynamic list.  */
5701218822Sdim  if (link_info.dynamic_list)
5702218822Sdim    lang_finalize_version_expr_head (&link_info.dynamic_list->head);
5703218822Sdim
570433965Sjdp  current_target = default_target;
570533965Sjdp
570677298Sobrien  /* Open the output file.  */
570777298Sobrien  lang_for_each_statement (ldlang_open_output);
5708130561Sobrien  init_opb ();
570933965Sjdp
571033965Sjdp  ldemul_create_output_section_statements ();
571133965Sjdp
571277298Sobrien  /* Add to the hash table all undefineds on the command line.  */
571333965Sjdp  lang_place_undefineds ();
571433965Sjdp
5715218822Sdim  if (!bfd_section_already_linked_table_init ())
5716218822Sdim    einfo (_("%P%F: Failed to create hash table\n"));
571760484Sobrien
571877298Sobrien  /* Create a bfd for each input file.  */
571933965Sjdp  current_target = default_target;
5720130561Sobrien  open_input_bfds (statement_list.head, FALSE);
572133965Sjdp
5722104834Sobrien  link_info.gc_sym_list = &entry_symbol;
5723104834Sobrien  if (entry_symbol.name == NULL)
5724104834Sobrien    link_info.gc_sym_list = ldlang_undef_chain_list_head;
5725104834Sobrien
572633965Sjdp  ldemul_after_open ();
572733965Sjdp
5728218822Sdim  bfd_section_already_linked_table_free ();
572960484Sobrien
573033965Sjdp  /* Make sure that we're not mixing architectures.  We call this
573133965Sjdp     after all the input files have been opened, but before we do any
573233965Sjdp     other processing, so that any operations merge_private_bfd_data
573333965Sjdp     does on the output file will be known during the rest of the
573433965Sjdp     link.  */
573533965Sjdp  lang_check ();
573633965Sjdp
573760484Sobrien  /* Handle .exports instead of a version script if we're told to do so.  */
573860484Sobrien  if (command_line.version_exports_section)
573960484Sobrien    lang_do_version_exports_section ();
574060484Sobrien
574133965Sjdp  /* Build all sets based on the information gathered from the input
574233965Sjdp     files.  */
574333965Sjdp  ldctor_build_sets ();
574433965Sjdp
574560484Sobrien  /* Remove unreferenced sections if asked to.  */
5746218822Sdim  lang_gc_sections ();
574760484Sobrien
574877298Sobrien  /* Size up the common data.  */
574933965Sjdp  lang_common ();
575033965Sjdp
5751218822Sdim  /* Update wild statements.  */
5752218822Sdim  update_wild_statements (statement_list.head);
5753218822Sdim
575433965Sjdp  /* Run through the contours of the script and attach input sections
575577298Sobrien     to the correct output sections.  */
5756130561Sobrien  map_input_to_output_sections (statement_list.head, NULL, NULL);
575733965Sjdp
575877298Sobrien  /* Find any sections not attached explicitly and handle them.  */
575933965Sjdp  lang_place_orphans ();
576033965Sjdp
5761130561Sobrien  if (! link_info.relocatable)
576294536Sobrien    {
5763218822Sdim      asection *found;
5764218822Sdim
5765218822Sdim      /* Merge SEC_MERGE sections.  This has to be done after GC of
5766218822Sdim	 sections, so that GCed sections are not merged, but before
5767218822Sdim	 assigning dynamic symbols, since removing whole input sections
5768218822Sdim	 is hard then.  */
5769218822Sdim      bfd_merge_sections (output_bfd, &link_info);
5770218822Sdim
577194536Sobrien      /* Look for a text section and set the readonly attribute in it.  */
5772218822Sdim      found = bfd_get_section_by_name (output_bfd, ".text");
577394536Sobrien
5774130561Sobrien      if (found != NULL)
577594536Sobrien	{
577694536Sobrien	  if (config.text_read_only)
577794536Sobrien	    found->flags |= SEC_READONLY;
577894536Sobrien	  else
577994536Sobrien	    found->flags &= ~SEC_READONLY;
578094536Sobrien	}
578194536Sobrien    }
578294536Sobrien
578394536Sobrien  /* Do anything special before sizing sections.  This is where ELF
578494536Sobrien     and other back-ends size dynamic sections.  */
578533965Sjdp  ldemul_before_allocation ();
578633965Sjdp
578733965Sjdp  /* We must record the program headers before we try to fix the
578833965Sjdp     section positions, since they will affect SIZEOF_HEADERS.  */
578933965Sjdp  lang_record_phdrs ();
579033965Sjdp
579189857Sobrien  /* Size up the sections.  */
5792218822Sdim  lang_size_sections (NULL, !command_line.relax);
579389857Sobrien
579477298Sobrien  /* Now run around and relax if we can.  */
579533965Sjdp  if (command_line.relax)
579633965Sjdp    {
5797218822Sdim      /* We may need more than one relaxation pass.  */
5798218822Sdim      int i = link_info.relax_pass;
579933965Sjdp
5800218822Sdim      /* The backend can use it to determine the current pass.  */
5801218822Sdim      link_info.relax_pass = 0;
5802218822Sdim
5803218822Sdim      while (i--)
580433965Sjdp	{
5805218822Sdim	  relax_sections ();
5806218822Sdim	  link_info.relax_pass++;
580733965Sjdp	}
5808130561Sobrien
5809130561Sobrien      /* Final extra sizing to report errors.  */
5810218822Sdim      lang_do_assignments ();
5811130561Sobrien      lang_reset_memory_regions ();
5812218822Sdim      lang_size_sections (NULL, TRUE);
581333965Sjdp    }
581433965Sjdp
581533965Sjdp  /* See if anything special should be done now we know how big
581633965Sjdp     everything is.  */
581733965Sjdp  ldemul_after_allocation ();
581833965Sjdp
581933965Sjdp  /* Fix any .startof. or .sizeof. symbols.  */
582033965Sjdp  lang_set_startof ();
582133965Sjdp
582277298Sobrien  /* Do all the assignments, now that we know the final resting places
582377298Sobrien     of all the symbols.  */
582433965Sjdp
5825218822Sdim  lang_do_assignments ();
582633965Sjdp
5827218822Sdim  ldemul_finish ();
5828218822Sdim
582960484Sobrien  /* Make sure that the section addresses make sense.  */
5830130561Sobrien  if (! link_info.relocatable
583160484Sobrien      && command_line.check_section_addresses)
583260484Sobrien    lang_check_section_addresses ();
583333965Sjdp
5834218822Sdim  lang_end ();
583533965Sjdp}
583633965Sjdp
583733965Sjdp/* EXPORTED TO YACC */
583833965Sjdp
583933965Sjdpvoid
5840130561Sobrienlang_add_wild (struct wildcard_spec *filespec,
5841130561Sobrien	       struct wildcard_list *section_list,
5842130561Sobrien	       bfd_boolean keep_sections)
584333965Sjdp{
584489857Sobrien  struct wildcard_list *curr, *next;
584589857Sobrien  lang_wild_statement_type *new;
584633965Sjdp
584789857Sobrien  /* Reverse the list as the parser puts it back to front.  */
584889857Sobrien  for (curr = section_list, section_list = NULL;
584989857Sobrien       curr != NULL;
585089857Sobrien       section_list = curr, curr = next)
585133965Sjdp    {
585289857Sobrien      if (curr->spec.name != NULL && strcmp (curr->spec.name, "COMMON") == 0)
5853130561Sobrien	placed_commons = TRUE;
585489857Sobrien
585589857Sobrien      next = curr->next;
585689857Sobrien      curr->next = section_list;
585733965Sjdp    }
585889857Sobrien
585989857Sobrien  if (filespec != NULL && filespec->name != NULL)
586033965Sjdp    {
586189857Sobrien      if (strcmp (filespec->name, "*") == 0)
586289857Sobrien	filespec->name = NULL;
586389857Sobrien      else if (! wildcardp (filespec->name))
5864130561Sobrien	lang_has_input_file = TRUE;
586533965Sjdp    }
586689857Sobrien
586789857Sobrien  new = new_stat (lang_wild_statement, stat_ptr);
586889857Sobrien  new->filename = NULL;
5869130561Sobrien  new->filenames_sorted = FALSE;
587089857Sobrien  if (filespec != NULL)
587189857Sobrien    {
587289857Sobrien      new->filename = filespec->name;
5873218822Sdim      new->filenames_sorted = filespec->sorted == by_name;
587489857Sobrien    }
587589857Sobrien  new->section_list = section_list;
587660484Sobrien  new->keep_sections = keep_sections;
587733965Sjdp  lang_list_init (&new->children);
5878218822Sdim  analyze_walk_wild_section_handler (new);
587933965Sjdp}
588033965Sjdp
588133965Sjdpvoid
5882218822Sdimlang_section_start (const char *name, etree_type *address,
5883218822Sdim		    const segment_type *segment)
588433965Sjdp{
588578828Sobrien  lang_address_statement_type *ad;
588633965Sjdp
588778828Sobrien  ad = new_stat (lang_address_statement, stat_ptr);
588833965Sjdp  ad->section_name = name;
588933965Sjdp  ad->address = address;
5890218822Sdim  ad->segment = segment;
589133965Sjdp}
589233965Sjdp
589333965Sjdp/* Set the start symbol to NAME.  CMDLINE is nonzero if this is called
589433965Sjdp   because of a -e argument on the command line, or zero if this is
589533965Sjdp   called by ENTRY in a linker script.  Command line arguments take
589633965Sjdp   precedence.  */
589733965Sjdp
589833965Sjdpvoid
5899130561Sobrienlang_add_entry (const char *name, bfd_boolean cmdline)
590033965Sjdp{
5901104834Sobrien  if (entry_symbol.name == NULL
590233965Sjdp      || cmdline
590333965Sjdp      || ! entry_from_cmdline)
590433965Sjdp    {
5905104834Sobrien      entry_symbol.name = name;
590633965Sjdp      entry_from_cmdline = cmdline;
590733965Sjdp    }
590833965Sjdp}
590933965Sjdp
5910218822Sdim/* Set the default start symbol to NAME.  .em files should use this,
5911218822Sdim   not lang_add_entry, to override the use of "start" if neither the
5912218822Sdim   linker script nor the command line specifies an entry point.  NAME
5913218822Sdim   must be permanently allocated.  */
591433965Sjdpvoid
5915218822Sdimlang_default_entry (const char *name)
5916218822Sdim{
5917218822Sdim  entry_symbol_default = name;
5918218822Sdim}
5919218822Sdim
5920218822Sdimvoid
5921130561Sobrienlang_add_target (const char *name)
592233965Sjdp{
5923218822Sdim  lang_target_statement_type *new;
592433965Sjdp
5925218822Sdim  new = new_stat (lang_target_statement, stat_ptr);
592633965Sjdp  new->target = name;
592733965Sjdp}
592833965Sjdp
592933965Sjdpvoid
5930130561Sobrienlang_add_map (const char *name)
593133965Sjdp{
593233965Sjdp  while (*name)
593333965Sjdp    {
593433965Sjdp      switch (*name)
593533965Sjdp	{
593677298Sobrien	case 'F':
5937130561Sobrien	  map_option_f = TRUE;
593833965Sjdp	  break;
593933965Sjdp	}
594033965Sjdp      name++;
594133965Sjdp    }
594233965Sjdp}
594333965Sjdp
594433965Sjdpvoid
5945130561Sobrienlang_add_fill (fill_type *fill)
594633965Sjdp{
5947218822Sdim  lang_fill_statement_type *new;
594833965Sjdp
5949218822Sdim  new = new_stat (lang_fill_statement, stat_ptr);
5950104834Sobrien  new->fill = fill;
595133965Sjdp}
595233965Sjdp
595333965Sjdpvoid
5954130561Sobrienlang_add_data (int type, union etree_union *exp)
595533965Sjdp{
5956218822Sdim  lang_data_statement_type *new;
595733965Sjdp
5958218822Sdim  new = new_stat (lang_data_statement, stat_ptr);
595933965Sjdp  new->exp = exp;
596033965Sjdp  new->type = type;
596133965Sjdp}
596233965Sjdp
596333965Sjdp/* Create a new reloc statement.  RELOC is the BFD relocation type to
596433965Sjdp   generate.  HOWTO is the corresponding howto structure (we could
596533965Sjdp   look this up, but the caller has already done so).  SECTION is the
596633965Sjdp   section to generate a reloc against, or NAME is the name of the
596733965Sjdp   symbol to generate a reloc against.  Exactly one of SECTION and
596833965Sjdp   NAME must be NULL.  ADDEND is an expression for the addend.  */
596933965Sjdp
597033965Sjdpvoid
5971130561Sobrienlang_add_reloc (bfd_reloc_code_real_type reloc,
5972130561Sobrien		reloc_howto_type *howto,
5973130561Sobrien		asection *section,
5974130561Sobrien		const char *name,
5975130561Sobrien		union etree_union *addend)
597633965Sjdp{
597733965Sjdp  lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr);
597877298Sobrien
597933965Sjdp  p->reloc = reloc;
598033965Sjdp  p->howto = howto;
598133965Sjdp  p->section = section;
598233965Sjdp  p->name = name;
598333965Sjdp  p->addend_exp = addend;
598433965Sjdp
598533965Sjdp  p->addend_value = 0;
598633965Sjdp  p->output_section = NULL;
5987218822Sdim  p->output_offset = 0;
598833965Sjdp}
598933965Sjdp
599060484Sobrienlang_assignment_statement_type *
5991130561Sobrienlang_add_assignment (etree_type *exp)
599233965Sjdp{
5993218822Sdim  lang_assignment_statement_type *new;
599433965Sjdp
5995218822Sdim  new = new_stat (lang_assignment_statement, stat_ptr);
599633965Sjdp  new->exp = exp;
599760484Sobrien  return new;
599833965Sjdp}
599933965Sjdp
600033965Sjdpvoid
6001130561Sobrienlang_add_attribute (enum statement_enum attribute)
600233965Sjdp{
6003218822Sdim  new_statement (attribute, sizeof (lang_statement_header_type), stat_ptr);
600433965Sjdp}
600533965Sjdp
600633965Sjdpvoid
6007130561Sobrienlang_startup (const char *name)
600833965Sjdp{
6009130561Sobrien  if (startup_file != NULL)
601033965Sjdp    {
6011218822Sdim      einfo (_("%P%F: multiple STARTUP files\n"));
601233965Sjdp    }
601333965Sjdp  first_file->filename = name;
601433965Sjdp  first_file->local_sym_name = name;
6015130561Sobrien  first_file->real = TRUE;
601633965Sjdp
601733965Sjdp  startup_file = name;
601833965Sjdp}
601933965Sjdp
602033965Sjdpvoid
6021130561Sobrienlang_float (bfd_boolean maybe)
602233965Sjdp{
602333965Sjdp  lang_float_flag = maybe;
602433965Sjdp}
602533965Sjdp
6026104834Sobrien
6027104834Sobrien/* Work out the load- and run-time regions from a script statement, and
6028104834Sobrien   store them in *LMA_REGION and *REGION respectively.
6029104834Sobrien
6030130561Sobrien   MEMSPEC is the name of the run-time region, or the value of
6031130561Sobrien   DEFAULT_MEMORY_REGION if the statement didn't specify one.
6032130561Sobrien   LMA_MEMSPEC is the name of the load-time region, or null if the
6033130561Sobrien   statement didn't specify one.HAVE_LMA_P is TRUE if the statement
6034130561Sobrien   had an explicit load address.
6035104834Sobrien
6036104834Sobrien   It is an error to specify both a load region and a load address.  */
6037104834Sobrien
6038104834Sobrienstatic void
6039130561Sobrienlang_get_regions (lang_memory_region_type **region,
6040130561Sobrien		  lang_memory_region_type **lma_region,
6041130561Sobrien		  const char *memspec,
6042130561Sobrien		  const char *lma_memspec,
6043130561Sobrien		  bfd_boolean have_lma,
6044130561Sobrien		  bfd_boolean have_vma)
6045104834Sobrien{
6046130561Sobrien  *lma_region = lang_memory_region_lookup (lma_memspec, FALSE);
6047104834Sobrien
6048218822Sdim  /* If no runtime region or VMA has been specified, but the load region
6049218822Sdim     has been specified, then use the load region for the runtime region
6050218822Sdim     as well.  */
6051130561Sobrien  if (lma_memspec != NULL
6052130561Sobrien      && ! have_vma
6053130561Sobrien      && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0)
6054104834Sobrien    *region = *lma_region;
6055104834Sobrien  else
6056130561Sobrien    *region = lang_memory_region_lookup (memspec, FALSE);
6057104834Sobrien
6058130561Sobrien  if (have_lma && lma_memspec != 0)
6059104834Sobrien    einfo (_("%X%P:%S: section has both a load address and a load region\n"));
6060104834Sobrien}
6061104834Sobrien
606233965Sjdpvoid
6063130561Sobrienlang_leave_output_section_statement (fill_type *fill, const char *memspec,
6064130561Sobrien				     lang_output_section_phdr_list *phdrs,
6065130561Sobrien				     const char *lma_memspec)
606633965Sjdp{
6067104834Sobrien  lang_get_regions (&current_section->region,
6068104834Sobrien		    &current_section->lma_region,
6069104834Sobrien		    memspec, lma_memspec,
6070130561Sobrien		    current_section->load_base != NULL,
6071130561Sobrien		    current_section->addr_tree != NULL);
607233965Sjdp  current_section->fill = fill;
607333965Sjdp  current_section->phdrs = phdrs;
607433965Sjdp  stat_ptr = &statement_list;
607533965Sjdp}
607633965Sjdp
607777298Sobrien/* Create an absolute symbol with the given name with the value of the
607877298Sobrien   address of first byte of the section named.
607933965Sjdp
608077298Sobrien   If the symbol already exists, then do nothing.  */
608177298Sobrien
608233965Sjdpvoid
6083130561Sobrienlang_abs_symbol_at_beginning_of (const char *secname, const char *name)
608433965Sjdp{
608533965Sjdp  struct bfd_link_hash_entry *h;
608633965Sjdp
6087130561Sobrien  h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE);
6088130561Sobrien  if (h == NULL)
608960484Sobrien    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
609033965Sjdp
609133965Sjdp  if (h->type == bfd_link_hash_new
609233965Sjdp      || h->type == bfd_link_hash_undefined)
609333965Sjdp    {
609433965Sjdp      asection *sec;
609533965Sjdp
609633965Sjdp      h->type = bfd_link_hash_defined;
609733965Sjdp
609833965Sjdp      sec = bfd_get_section_by_name (output_bfd, secname);
6099130561Sobrien      if (sec == NULL)
610033965Sjdp	h->u.def.value = 0;
610133965Sjdp      else
610233965Sjdp	h->u.def.value = bfd_get_section_vma (output_bfd, sec);
610333965Sjdp
610433965Sjdp      h->u.def.section = bfd_abs_section_ptr;
610533965Sjdp    }
610633965Sjdp}
610733965Sjdp
610877298Sobrien/* Create an absolute symbol with the given name with the value of the
610977298Sobrien   address of the first byte after the end of the section named.
611033965Sjdp
611177298Sobrien   If the symbol already exists, then do nothing.  */
611277298Sobrien
611333965Sjdpvoid
6114130561Sobrienlang_abs_symbol_at_end_of (const char *secname, const char *name)
611533965Sjdp{
611633965Sjdp  struct bfd_link_hash_entry *h;
611733965Sjdp
6118130561Sobrien  h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE);
6119130561Sobrien  if (h == NULL)
612060484Sobrien    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
612133965Sjdp
612233965Sjdp  if (h->type == bfd_link_hash_new
612333965Sjdp      || h->type == bfd_link_hash_undefined)
612433965Sjdp    {
612533965Sjdp      asection *sec;
612633965Sjdp
612733965Sjdp      h->type = bfd_link_hash_defined;
612833965Sjdp
612933965Sjdp      sec = bfd_get_section_by_name (output_bfd, secname);
6130130561Sobrien      if (sec == NULL)
613133965Sjdp	h->u.def.value = 0;
613233965Sjdp      else
613333965Sjdp	h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
6134218822Sdim			  + TO_ADDR (sec->size));
613533965Sjdp
613633965Sjdp      h->u.def.section = bfd_abs_section_ptr;
613733965Sjdp    }
613833965Sjdp}
613933965Sjdp
614033965Sjdpvoid
6141130561Sobrienlang_statement_append (lang_statement_list_type *list,
6142130561Sobrien		       lang_statement_union_type *element,
6143130561Sobrien		       lang_statement_union_type **field)
614433965Sjdp{
614533965Sjdp  *(list->tail) = element;
614633965Sjdp  list->tail = field;
614733965Sjdp}
614833965Sjdp
614933965Sjdp/* Set the output format type.  -oformat overrides scripts.  */
615033965Sjdp
615133965Sjdpvoid
6152130561Sobrienlang_add_output_format (const char *format,
6153130561Sobrien			const char *big,
6154130561Sobrien			const char *little,
6155130561Sobrien			int from_script)
615633965Sjdp{
615733965Sjdp  if (output_target == NULL || !from_script)
615833965Sjdp    {
615933965Sjdp      if (command_line.endian == ENDIAN_BIG
616033965Sjdp	  && big != NULL)
616133965Sjdp	format = big;
616233965Sjdp      else if (command_line.endian == ENDIAN_LITTLE
616333965Sjdp	       && little != NULL)
616433965Sjdp	format = little;
616533965Sjdp
616633965Sjdp      output_target = format;
616733965Sjdp    }
616833965Sjdp}
616933965Sjdp
617033965Sjdp/* Enter a group.  This creates a new lang_group_statement, and sets
617133965Sjdp   stat_ptr to build new statements within the group.  */
617233965Sjdp
617333965Sjdpvoid
6174130561Sobrienlang_enter_group (void)
617533965Sjdp{
617633965Sjdp  lang_group_statement_type *g;
617733965Sjdp
617833965Sjdp  g = new_stat (lang_group_statement, stat_ptr);
617933965Sjdp  lang_list_init (&g->children);
618033965Sjdp  stat_ptr = &g->children;
618133965Sjdp}
618233965Sjdp
618333965Sjdp/* Leave a group.  This just resets stat_ptr to start writing to the
618433965Sjdp   regular list of statements again.  Note that this will not work if
618533965Sjdp   groups can occur inside anything else which can adjust stat_ptr,
618633965Sjdp   but currently they can't.  */
618733965Sjdp
618833965Sjdpvoid
6189130561Sobrienlang_leave_group (void)
619033965Sjdp{
619133965Sjdp  stat_ptr = &statement_list;
619233965Sjdp}
619333965Sjdp
619433965Sjdp/* Add a new program header.  This is called for each entry in a PHDRS
619533965Sjdp   command in a linker script.  */
619633965Sjdp
619733965Sjdpvoid
6198130561Sobrienlang_new_phdr (const char *name,
6199130561Sobrien	       etree_type *type,
6200130561Sobrien	       bfd_boolean filehdr,
6201130561Sobrien	       bfd_boolean phdrs,
6202130561Sobrien	       etree_type *at,
6203130561Sobrien	       etree_type *flags)
620433965Sjdp{
620533965Sjdp  struct lang_phdr *n, **pp;
620633965Sjdp
6207130561Sobrien  n = stat_alloc (sizeof (struct lang_phdr));
620833965Sjdp  n->next = NULL;
620933965Sjdp  n->name = name;
6210218822Sdim  n->type = exp_get_value_int (type, 0, "program header type");
621133965Sjdp  n->filehdr = filehdr;
621233965Sjdp  n->phdrs = phdrs;
621333965Sjdp  n->at = at;
621433965Sjdp  n->flags = flags;
621533965Sjdp
621633965Sjdp  for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next)
621733965Sjdp    ;
621833965Sjdp  *pp = n;
621933965Sjdp}
622033965Sjdp
622133965Sjdp/* Record the program header information in the output BFD.  FIXME: We
622233965Sjdp   should not be calling an ELF specific function here.  */
622333965Sjdp
622433965Sjdpstatic void
6225130561Sobrienlang_record_phdrs (void)
622633965Sjdp{
622733965Sjdp  unsigned int alc;
622833965Sjdp  asection **secs;
6229130561Sobrien  lang_output_section_phdr_list *last;
623033965Sjdp  struct lang_phdr *l;
6231218822Sdim  lang_output_section_statement_type *os;
623233965Sjdp
623333965Sjdp  alc = 10;
6234130561Sobrien  secs = xmalloc (alc * sizeof (asection *));
623533965Sjdp  last = NULL;
6236218822Sdim
623733965Sjdp  for (l = lang_phdr_list; l != NULL; l = l->next)
623833965Sjdp    {
623933965Sjdp      unsigned int c;
624033965Sjdp      flagword flags;
624133965Sjdp      bfd_vma at;
624233965Sjdp
624333965Sjdp      c = 0;
6244218822Sdim      for (os = &lang_output_section_statement.head->output_section_statement;
6245218822Sdim	   os != NULL;
6246218822Sdim	   os = os->next)
624733965Sjdp	{
6248130561Sobrien	  lang_output_section_phdr_list *pl;
624933965Sjdp
6250218822Sdim	  if (os->constraint == -1)
6251218822Sdim	    continue;
625233965Sjdp
625333965Sjdp	  pl = os->phdrs;
625433965Sjdp	  if (pl != NULL)
625533965Sjdp	    last = pl;
625633965Sjdp	  else
625733965Sjdp	    {
625833965Sjdp	      if (os->sectype == noload_section
625933965Sjdp		  || os->bfd_section == NULL
626033965Sjdp		  || (os->bfd_section->flags & SEC_ALLOC) == 0)
626133965Sjdp		continue;
6262218822Sdim
6263218822Sdim	      if (last)
6264218822Sdim		pl = last;
6265218822Sdim	      else
6266218822Sdim		{
6267218822Sdim		  lang_output_section_statement_type * tmp_os;
6268218822Sdim
6269218822Sdim		  /* If we have not run across a section with a program
6270218822Sdim		     header assigned to it yet, then scan forwards to find
6271218822Sdim		     one.  This prevents inconsistencies in the linker's
6272218822Sdim		     behaviour when a script has specified just a single
6273218822Sdim		     header and there are sections in that script which are
6274218822Sdim		     not assigned to it, and which occur before the first
6275218822Sdim		     use of that header. See here for more details:
6276218822Sdim		     http://sourceware.org/ml/binutils/2007-02/msg00291.html  */
6277218822Sdim		  for (tmp_os = os; tmp_os; tmp_os = tmp_os->next)
6278218822Sdim		    if (tmp_os->phdrs)
6279218822Sdim		      break;
6280218822Sdim		  pl = tmp_os->phdrs;
6281218822Sdim		}
628233965Sjdp	    }
628333965Sjdp
628433965Sjdp	  if (os->bfd_section == NULL)
628533965Sjdp	    continue;
628633965Sjdp
628733965Sjdp	  for (; pl != NULL; pl = pl->next)
628833965Sjdp	    {
628933965Sjdp	      if (strcmp (pl->name, l->name) == 0)
629033965Sjdp		{
629133965Sjdp		  if (c >= alc)
629233965Sjdp		    {
629333965Sjdp		      alc *= 2;
6294130561Sobrien		      secs = xrealloc (secs, alc * sizeof (asection *));
629533965Sjdp		    }
629633965Sjdp		  secs[c] = os->bfd_section;
629733965Sjdp		  ++c;
6298130561Sobrien		  pl->used = TRUE;
629933965Sjdp		}
630033965Sjdp	    }
630133965Sjdp	}
630233965Sjdp
630333965Sjdp      if (l->flags == NULL)
630433965Sjdp	flags = 0;
630533965Sjdp      else
6306218822Sdim	flags = exp_get_vma (l->flags, 0, "phdr flags");
630733965Sjdp
630833965Sjdp      if (l->at == NULL)
630933965Sjdp	at = 0;
631033965Sjdp      else
6311218822Sdim	at = exp_get_vma (l->at, 0, "phdr load address");
631233965Sjdp
631333965Sjdp      if (! bfd_record_phdr (output_bfd, l->type,
631478828Sobrien			     l->flags != NULL, flags, l->at != NULL,
631533965Sjdp			     at, l->filehdr, l->phdrs, c, secs))
631660484Sobrien	einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
631733965Sjdp    }
631833965Sjdp
631933965Sjdp  free (secs);
632033965Sjdp
632133965Sjdp  /* Make sure all the phdr assignments succeeded.  */
6322218822Sdim  for (os = &lang_output_section_statement.head->output_section_statement;
6323218822Sdim       os != NULL;
6324218822Sdim       os = os->next)
632533965Sjdp    {
6326130561Sobrien      lang_output_section_phdr_list *pl;
632733965Sjdp
6328218822Sdim      if (os->constraint == -1
6329218822Sdim	  || os->bfd_section == NULL)
633033965Sjdp	continue;
633133965Sjdp
6332218822Sdim      for (pl = os->phdrs;
633333965Sjdp	   pl != NULL;
633433965Sjdp	   pl = pl->next)
633533965Sjdp	if (! pl->used && strcmp (pl->name, "NONE") != 0)
633660484Sobrien	  einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"),
6337218822Sdim		 os->name, pl->name);
633833965Sjdp    }
633933965Sjdp}
634033965Sjdp
634133965Sjdp/* Record a list of sections which may not be cross referenced.  */
634233965Sjdp
634333965Sjdpvoid
6344130561Sobrienlang_add_nocrossref (lang_nocrossref_type *l)
634533965Sjdp{
634633965Sjdp  struct lang_nocrossrefs *n;
634733965Sjdp
6348130561Sobrien  n = xmalloc (sizeof *n);
634933965Sjdp  n->next = nocrossref_list;
635033965Sjdp  n->list = l;
635133965Sjdp  nocrossref_list = n;
635233965Sjdp
635333965Sjdp  /* Set notice_all so that we get informed about all symbols.  */
6354130561Sobrien  link_info.notice_all = TRUE;
635533965Sjdp}
635633965Sjdp
635733965Sjdp/* Overlay handling.  We handle overlays with some static variables.  */
635833965Sjdp
635933965Sjdp/* The overlay virtual address.  */
636033965Sjdpstatic etree_type *overlay_vma;
6361130561Sobrien/* And subsection alignment.  */
6362130561Sobrienstatic etree_type *overlay_subalign;
636333965Sjdp
636433965Sjdp/* An expression for the maximum section size seen so far.  */
636533965Sjdpstatic etree_type *overlay_max;
636633965Sjdp
636733965Sjdp/* A list of all the sections in this overlay.  */
636833965Sjdp
636977298Sobrienstruct overlay_list {
637033965Sjdp  struct overlay_list *next;
637133965Sjdp  lang_output_section_statement_type *os;
637233965Sjdp};
637333965Sjdp
637433965Sjdpstatic struct overlay_list *overlay_list;
637533965Sjdp
637633965Sjdp/* Start handling an overlay.  */
637733965Sjdp
637833965Sjdpvoid
6379130561Sobrienlang_enter_overlay (etree_type *vma_expr, etree_type *subalign)
638033965Sjdp{
638133965Sjdp  /* The grammar should prevent nested overlays from occurring.  */
6382130561Sobrien  ASSERT (overlay_vma == NULL
6383130561Sobrien	  && overlay_subalign == NULL
6384130561Sobrien	  && overlay_max == NULL);
638533965Sjdp
638633965Sjdp  overlay_vma = vma_expr;
6387130561Sobrien  overlay_subalign = subalign;
638833965Sjdp}
638933965Sjdp
639033965Sjdp/* Start a section in an overlay.  We handle this by calling
6391104834Sobrien   lang_enter_output_section_statement with the correct VMA.
6392104834Sobrien   lang_leave_overlay sets up the LMA and memory regions.  */
639333965Sjdp
639433965Sjdpvoid
6395130561Sobrienlang_enter_overlay_section (const char *name)
639633965Sjdp{
639733965Sjdp  struct overlay_list *n;
639833965Sjdp  etree_type *size;
639933965Sjdp
6400218822Sdim  lang_enter_output_section_statement (name, overlay_vma, overlay_section,
6401218822Sdim				       0, overlay_subalign, 0, 0);
640233965Sjdp
6403104834Sobrien  /* If this is the first section, then base the VMA of future
640433965Sjdp     sections on this one.  This will work correctly even if `.' is
640533965Sjdp     used in the addresses.  */
640633965Sjdp  if (overlay_list == NULL)
6407104834Sobrien    overlay_vma = exp_nameop (ADDR, name);
640833965Sjdp
640933965Sjdp  /* Remember the section.  */
6410130561Sobrien  n = xmalloc (sizeof *n);
641133965Sjdp  n->os = current_section;
641233965Sjdp  n->next = overlay_list;
641333965Sjdp  overlay_list = n;
641433965Sjdp
641533965Sjdp  size = exp_nameop (SIZEOF, name);
641633965Sjdp
641733965Sjdp  /* Arrange to work out the maximum section end address.  */
641833965Sjdp  if (overlay_max == NULL)
641933965Sjdp    overlay_max = size;
642033965Sjdp  else
642160484Sobrien    overlay_max = exp_binop (MAX_K, overlay_max, size);
642233965Sjdp}
642333965Sjdp
642433965Sjdp/* Finish a section in an overlay.  There isn't any special to do
642533965Sjdp   here.  */
642633965Sjdp
642733965Sjdpvoid
6428130561Sobrienlang_leave_overlay_section (fill_type *fill,
6429130561Sobrien			    lang_output_section_phdr_list *phdrs)
643033965Sjdp{
643133965Sjdp  const char *name;
643233965Sjdp  char *clean, *s2;
643333965Sjdp  const char *s1;
643433965Sjdp  char *buf;
643533965Sjdp
643633965Sjdp  name = current_section->name;
643733965Sjdp
6438130561Sobrien  /* For now, assume that DEFAULT_MEMORY_REGION is the run-time memory
6439130561Sobrien     region and that no load-time region has been specified.  It doesn't
6440130561Sobrien     really matter what we say here, since lang_leave_overlay will
6441130561Sobrien     override it.  */
6442130561Sobrien  lang_leave_output_section_statement (fill, DEFAULT_MEMORY_REGION, phdrs, 0);
644333965Sjdp
644433965Sjdp  /* Define the magic symbols.  */
644533965Sjdp
644633965Sjdp  clean = xmalloc (strlen (name) + 1);
644733965Sjdp  s2 = clean;
644833965Sjdp  for (s1 = name; *s1 != '\0'; s1++)
644989857Sobrien    if (ISALNUM (*s1) || *s1 == '_')
645033965Sjdp      *s2++ = *s1;
645133965Sjdp  *s2 = '\0';
645233965Sjdp
645333965Sjdp  buf = xmalloc (strlen (clean) + sizeof "__load_start_");
645433965Sjdp  sprintf (buf, "__load_start_%s", clean);
6455218822Sdim  lang_add_assignment (exp_provide (buf,
6456218822Sdim				    exp_nameop (LOADADDR, name),
6457218822Sdim				    FALSE));
645833965Sjdp
645933965Sjdp  buf = xmalloc (strlen (clean) + sizeof "__load_stop_");
646033965Sjdp  sprintf (buf, "__load_stop_%s", clean);
6461218822Sdim  lang_add_assignment (exp_provide (buf,
6462218822Sdim				    exp_binop ('+',
6463218822Sdim					       exp_nameop (LOADADDR, name),
6464218822Sdim					       exp_nameop (SIZEOF, name)),
6465218822Sdim				    FALSE));
646633965Sjdp
646733965Sjdp  free (clean);
646833965Sjdp}
646933965Sjdp
647033965Sjdp/* Finish an overlay.  If there are any overlay wide settings, this
647133965Sjdp   looks through all the sections in the overlay and sets them.  */
647233965Sjdp
647333965Sjdpvoid
6474130561Sobrienlang_leave_overlay (etree_type *lma_expr,
6475130561Sobrien		    int nocrossrefs,
6476130561Sobrien		    fill_type *fill,
6477130561Sobrien		    const char *memspec,
6478130561Sobrien		    lang_output_section_phdr_list *phdrs,
6479130561Sobrien		    const char *lma_memspec)
648033965Sjdp{
648133965Sjdp  lang_memory_region_type *region;
648260484Sobrien  lang_memory_region_type *lma_region;
648333965Sjdp  struct overlay_list *l;
6484130561Sobrien  lang_nocrossref_type *nocrossref;
648533965Sjdp
6486104834Sobrien  lang_get_regions (&region, &lma_region,
6487104834Sobrien		    memspec, lma_memspec,
6488130561Sobrien		    lma_expr != NULL, FALSE);
648980016Sobrien
6490104834Sobrien  nocrossref = NULL;
649133965Sjdp
6492104834Sobrien  /* After setting the size of the last section, set '.' to end of the
6493104834Sobrien     overlay region.  */
6494104834Sobrien  if (overlay_list != NULL)
6495104834Sobrien    overlay_list->os->update_dot_tree
6496104834Sobrien      = exp_assop ('=', ".", exp_binop ('+', overlay_vma, overlay_max));
649760484Sobrien
649833965Sjdp  l = overlay_list;
649933965Sjdp  while (l != NULL)
650033965Sjdp    {
650133965Sjdp      struct overlay_list *next;
650233965Sjdp
6503130561Sobrien      if (fill != NULL && l->os->fill == NULL)
650433965Sjdp	l->os->fill = fill;
650580016Sobrien
6506104834Sobrien      l->os->region = region;
6507104834Sobrien      l->os->lma_region = lma_region;
650880016Sobrien
6509104834Sobrien      /* The first section has the load address specified in the
6510104834Sobrien	 OVERLAY statement.  The rest are worked out from that.
6511104834Sobrien	 The base address is not needed (and should be null) if
6512104834Sobrien	 an LMA region was specified.  */
6513104834Sobrien      if (l->next == 0)
6514218822Sdim	{
6515218822Sdim	  l->os->load_base = lma_expr;
6516218822Sdim	  l->os->sectype = normal_section;
6517218822Sdim	}
651833965Sjdp      if (phdrs != NULL && l->os->phdrs == NULL)
651933965Sjdp	l->os->phdrs = phdrs;
652033965Sjdp
6521104834Sobrien      if (nocrossrefs)
652233965Sjdp	{
6523130561Sobrien	  lang_nocrossref_type *nc;
652433965Sjdp
6525130561Sobrien	  nc = xmalloc (sizeof *nc);
652633965Sjdp	  nc->name = l->os->name;
652733965Sjdp	  nc->next = nocrossref;
652833965Sjdp	  nocrossref = nc;
652933965Sjdp	}
653033965Sjdp
653133965Sjdp      next = l->next;
653233965Sjdp      free (l);
653333965Sjdp      l = next;
653433965Sjdp    }
653533965Sjdp
653633965Sjdp  if (nocrossref != NULL)
653733965Sjdp    lang_add_nocrossref (nocrossref);
653833965Sjdp
653933965Sjdp  overlay_vma = NULL;
654033965Sjdp  overlay_list = NULL;
654133965Sjdp  overlay_max = NULL;
654233965Sjdp}
654333965Sjdp
654433965Sjdp/* Version handling.  This is only useful for ELF.  */
654533965Sjdp
654633965Sjdp/* This global variable holds the version tree that we build.  */
654733965Sjdp
654833965Sjdpstruct bfd_elf_version_tree *lang_elf_version_info;
654933965Sjdp
6550130561Sobrien/* If PREV is NULL, return first version pattern matching particular symbol.
6551130561Sobrien   If PREV is non-NULL, return first version pattern matching particular
6552130561Sobrien   symbol after PREV (previously returned by lang_vers_match).  */
655360484Sobrien
6554130561Sobrienstatic struct bfd_elf_version_expr *
6555130561Sobrienlang_vers_match (struct bfd_elf_version_expr_head *head,
6556130561Sobrien		 struct bfd_elf_version_expr *prev,
6557130561Sobrien		 const char *sym)
655860484Sobrien{
6559130561Sobrien  const char *cxx_sym = sym;
6560130561Sobrien  const char *java_sym = sym;
6561130561Sobrien  struct bfd_elf_version_expr *expr = NULL;
656260484Sobrien
6563130561Sobrien  if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
6564130561Sobrien    {
6565130561Sobrien      cxx_sym = cplus_demangle (sym, DMGL_PARAMS | DMGL_ANSI);
6566130561Sobrien      if (!cxx_sym)
6567130561Sobrien	cxx_sym = sym;
6568130561Sobrien    }
6569130561Sobrien  if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
6570130561Sobrien    {
6571130561Sobrien      java_sym = cplus_demangle (sym, DMGL_JAVA);
6572130561Sobrien      if (!java_sym)
6573130561Sobrien	java_sym = sym;
6574130561Sobrien    }
657560484Sobrien
6576130561Sobrien  if (head->htab && (prev == NULL || prev->symbol))
657760484Sobrien    {
6578130561Sobrien      struct bfd_elf_version_expr e;
6579130561Sobrien
6580130561Sobrien      switch (prev ? prev->mask : 0)
6581130561Sobrien	{
6582130561Sobrien	  case 0:
6583130561Sobrien	    if (head->mask & BFD_ELF_VERSION_C_TYPE)
6584130561Sobrien	      {
6585130561Sobrien		e.symbol = sym;
6586130561Sobrien		expr = htab_find (head->htab, &e);
6587130561Sobrien		while (expr && strcmp (expr->symbol, sym) == 0)
6588130561Sobrien		  if (expr->mask == BFD_ELF_VERSION_C_TYPE)
6589130561Sobrien		    goto out_ret;
6590218822Sdim		  else
6591218822Sdim		    expr = expr->next;
6592130561Sobrien	      }
6593130561Sobrien	    /* Fallthrough */
6594130561Sobrien	  case BFD_ELF_VERSION_C_TYPE:
6595130561Sobrien	    if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
6596130561Sobrien	      {
6597130561Sobrien		e.symbol = cxx_sym;
6598130561Sobrien		expr = htab_find (head->htab, &e);
6599130561Sobrien		while (expr && strcmp (expr->symbol, cxx_sym) == 0)
6600130561Sobrien		  if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
6601130561Sobrien		    goto out_ret;
6602218822Sdim		  else
6603218822Sdim		    expr = expr->next;
6604130561Sobrien	      }
6605130561Sobrien	    /* Fallthrough */
6606130561Sobrien	  case BFD_ELF_VERSION_CXX_TYPE:
6607130561Sobrien	    if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
6608130561Sobrien	      {
6609130561Sobrien		e.symbol = java_sym;
6610130561Sobrien		expr = htab_find (head->htab, &e);
6611130561Sobrien		while (expr && strcmp (expr->symbol, java_sym) == 0)
6612130561Sobrien		  if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
6613130561Sobrien		    goto out_ret;
6614218822Sdim		  else
6615218822Sdim		    expr = expr->next;
6616130561Sobrien	      }
6617130561Sobrien	    /* Fallthrough */
6618130561Sobrien	  default:
6619130561Sobrien	    break;
6620130561Sobrien	}
662160484Sobrien    }
6622130561Sobrien
6623130561Sobrien  /* Finally, try the wildcards.  */
6624130561Sobrien  if (prev == NULL || prev->symbol)
6625130561Sobrien    expr = head->remaining;
662660484Sobrien  else
6627130561Sobrien    expr = prev->next;
6628218822Sdim  for (; expr; expr = expr->next)
662960484Sobrien    {
6630130561Sobrien      const char *s;
6631130561Sobrien
6632218822Sdim      if (!expr->pattern)
6633218822Sdim	continue;
6634218822Sdim
6635130561Sobrien      if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
6636130561Sobrien	break;
6637130561Sobrien
6638130561Sobrien      if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
6639130561Sobrien	s = java_sym;
6640130561Sobrien      else if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
6641130561Sobrien	s = cxx_sym;
6642130561Sobrien      else
6643130561Sobrien	s = sym;
6644130561Sobrien      if (fnmatch (expr->pattern, s, 0) == 0)
6645130561Sobrien	break;
664660484Sobrien    }
664760484Sobrien
6648130561Sobrienout_ret:
6649130561Sobrien  if (cxx_sym != sym)
6650130561Sobrien    free ((char *) cxx_sym);
6651130561Sobrien  if (java_sym != sym)
6652130561Sobrien    free ((char *) java_sym);
6653130561Sobrien  return expr;
665460484Sobrien}
665560484Sobrien
6656130561Sobrien/* Return NULL if the PATTERN argument is a glob pattern, otherwise,
6657130561Sobrien   return a string pointing to the symbol name.  */
6658130561Sobrien
6659130561Sobrienstatic const char *
6660130561Sobrienrealsymbol (const char *pattern)
666160484Sobrien{
6662130561Sobrien  const char *p;
6663130561Sobrien  bfd_boolean changed = FALSE, backslash = FALSE;
6664130561Sobrien  char *s, *symbol = xmalloc (strlen (pattern) + 1);
666560484Sobrien
6666130561Sobrien  for (p = pattern, s = symbol; *p != '\0'; ++p)
6667130561Sobrien    {
6668130561Sobrien      /* It is a glob pattern only if there is no preceding
6669130561Sobrien	 backslash.  */
6670130561Sobrien      if (! backslash && (*p == '?' || *p == '*' || *p == '['))
6671130561Sobrien	{
6672130561Sobrien	  free (symbol);
6673130561Sobrien	  return NULL;
6674130561Sobrien	}
667560484Sobrien
6676130561Sobrien      if (backslash)
6677130561Sobrien	{
6678130561Sobrien	  /* Remove the preceding backslash.  */
6679130561Sobrien	  *(s - 1) = *p;
6680130561Sobrien	  changed = TRUE;
6681130561Sobrien	}
6682130561Sobrien      else
6683130561Sobrien	*s++ = *p;
6684130561Sobrien
6685130561Sobrien      backslash = *p == '\\';
6686130561Sobrien    }
6687130561Sobrien
6688130561Sobrien  if (changed)
668960484Sobrien    {
6690130561Sobrien      *s = '\0';
6691130561Sobrien      return symbol;
669260484Sobrien    }
669360484Sobrien  else
669460484Sobrien    {
6695130561Sobrien      free (symbol);
6696130561Sobrien      return pattern;
669760484Sobrien    }
669860484Sobrien}
669960484Sobrien
6700218822Sdim/* This is called for each variable name or match expression.  NEW is
6701218822Sdim   the name of the symbol to match, or, if LITERAL_P is FALSE, a glob
6702218822Sdim   pattern to be matched against symbol names.  */
670333965Sjdp
670433965Sjdpstruct bfd_elf_version_expr *
6705130561Sobrienlang_new_vers_pattern (struct bfd_elf_version_expr *orig,
6706130561Sobrien		       const char *new,
6707218822Sdim		       const char *lang,
6708218822Sdim		       bfd_boolean literal_p)
670933965Sjdp{
671033965Sjdp  struct bfd_elf_version_expr *ret;
671133965Sjdp
6712130561Sobrien  ret = xmalloc (sizeof *ret);
671333965Sjdp  ret->next = orig;
6714218822Sdim  ret->pattern = literal_p ? NULL : new;
6715104834Sobrien  ret->symver = 0;
6716104834Sobrien  ret->script = 0;
6717218822Sdim  ret->symbol = literal_p ? new : realsymbol (new);
671860484Sobrien
671960484Sobrien  if (lang == NULL || strcasecmp (lang, "C") == 0)
6720130561Sobrien    ret->mask = BFD_ELF_VERSION_C_TYPE;
672160484Sobrien  else if (strcasecmp (lang, "C++") == 0)
6722130561Sobrien    ret->mask = BFD_ELF_VERSION_CXX_TYPE;
672360484Sobrien  else if (strcasecmp (lang, "Java") == 0)
6724130561Sobrien    ret->mask = BFD_ELF_VERSION_JAVA_TYPE;
672560484Sobrien  else
672660484Sobrien    {
672760484Sobrien      einfo (_("%X%P: unknown language `%s' in version information\n"),
672860484Sobrien	     lang);
6729130561Sobrien      ret->mask = BFD_ELF_VERSION_C_TYPE;
673060484Sobrien    }
673160484Sobrien
6732104834Sobrien  return ldemul_new_vers_pattern (ret);
673333965Sjdp}
673433965Sjdp
673533965Sjdp/* This is called for each set of variable names and match
673633965Sjdp   expressions.  */
673733965Sjdp
673833965Sjdpstruct bfd_elf_version_tree *
6739130561Sobrienlang_new_vers_node (struct bfd_elf_version_expr *globals,
6740130561Sobrien		    struct bfd_elf_version_expr *locals)
674133965Sjdp{
674233965Sjdp  struct bfd_elf_version_tree *ret;
674333965Sjdp
6744130561Sobrien  ret = xcalloc (1, sizeof *ret);
6745130561Sobrien  ret->globals.list = globals;
6746130561Sobrien  ret->locals.list = locals;
6747130561Sobrien  ret->match = lang_vers_match;
674833965Sjdp  ret->name_indx = (unsigned int) -1;
674933965Sjdp  return ret;
675033965Sjdp}
675133965Sjdp
675233965Sjdp/* This static variable keeps track of version indices.  */
675333965Sjdp
675433965Sjdpstatic int version_index;
675533965Sjdp
6756130561Sobrienstatic hashval_t
6757130561Sobrienversion_expr_head_hash (const void *p)
6758130561Sobrien{
6759130561Sobrien  const struct bfd_elf_version_expr *e = p;
6760130561Sobrien
6761130561Sobrien  return htab_hash_string (e->symbol);
6762130561Sobrien}
6763130561Sobrien
6764130561Sobrienstatic int
6765130561Sobrienversion_expr_head_eq (const void *p1, const void *p2)
6766130561Sobrien{
6767130561Sobrien  const struct bfd_elf_version_expr *e1 = p1;
6768130561Sobrien  const struct bfd_elf_version_expr *e2 = p2;
6769130561Sobrien
6770130561Sobrien  return strcmp (e1->symbol, e2->symbol) == 0;
6771130561Sobrien}
6772130561Sobrien
6773130561Sobrienstatic void
6774130561Sobrienlang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
6775130561Sobrien{
6776130561Sobrien  size_t count = 0;
6777130561Sobrien  struct bfd_elf_version_expr *e, *next;
6778130561Sobrien  struct bfd_elf_version_expr **list_loc, **remaining_loc;
6779130561Sobrien
6780130561Sobrien  for (e = head->list; e; e = e->next)
6781130561Sobrien    {
6782130561Sobrien      if (e->symbol)
6783130561Sobrien	count++;
6784130561Sobrien      head->mask |= e->mask;
6785130561Sobrien    }
6786130561Sobrien
6787130561Sobrien  if (count)
6788130561Sobrien    {
6789130561Sobrien      head->htab = htab_create (count * 2, version_expr_head_hash,
6790130561Sobrien				version_expr_head_eq, NULL);
6791130561Sobrien      list_loc = &head->list;
6792130561Sobrien      remaining_loc = &head->remaining;
6793130561Sobrien      for (e = head->list; e; e = next)
6794130561Sobrien	{
6795130561Sobrien	  next = e->next;
6796130561Sobrien	  if (!e->symbol)
6797130561Sobrien	    {
6798130561Sobrien	      *remaining_loc = e;
6799130561Sobrien	      remaining_loc = &e->next;
6800130561Sobrien	    }
6801130561Sobrien	  else
6802130561Sobrien	    {
6803130561Sobrien	      void **loc = htab_find_slot (head->htab, e, INSERT);
6804130561Sobrien
6805130561Sobrien	      if (*loc)
6806130561Sobrien		{
6807130561Sobrien		  struct bfd_elf_version_expr *e1, *last;
6808130561Sobrien
6809130561Sobrien		  e1 = *loc;
6810130561Sobrien		  last = NULL;
6811130561Sobrien		  do
6812130561Sobrien		    {
6813130561Sobrien		      if (e1->mask == e->mask)
6814130561Sobrien			{
6815130561Sobrien			  last = NULL;
6816130561Sobrien			  break;
6817130561Sobrien			}
6818130561Sobrien		      last = e1;
6819130561Sobrien		      e1 = e1->next;
6820130561Sobrien		    }
6821130561Sobrien		  while (e1 && strcmp (e1->symbol, e->symbol) == 0);
6822130561Sobrien
6823130561Sobrien		  if (last == NULL)
6824130561Sobrien		    {
6825130561Sobrien		      /* This is a duplicate.  */
6826130561Sobrien		      /* FIXME: Memory leak.  Sometimes pattern is not
6827130561Sobrien			 xmalloced alone, but in larger chunk of memory.  */
6828130561Sobrien		      /* free (e->symbol); */
6829130561Sobrien		      free (e);
6830130561Sobrien		    }
6831130561Sobrien		  else
6832130561Sobrien		    {
6833130561Sobrien		      e->next = last->next;
6834130561Sobrien		      last->next = e;
6835130561Sobrien		    }
6836130561Sobrien		}
6837130561Sobrien	      else
6838130561Sobrien		{
6839130561Sobrien		  *loc = e;
6840130561Sobrien		  *list_loc = e;
6841130561Sobrien		  list_loc = &e->next;
6842130561Sobrien		}
6843130561Sobrien	    }
6844130561Sobrien	}
6845130561Sobrien      *remaining_loc = NULL;
6846130561Sobrien      *list_loc = head->remaining;
6847130561Sobrien    }
6848130561Sobrien  else
6849130561Sobrien    head->remaining = head->list;
6850130561Sobrien}
6851130561Sobrien
685233965Sjdp/* This is called when we know the name and dependencies of the
685333965Sjdp   version.  */
685433965Sjdp
685533965Sjdpvoid
6856130561Sobrienlang_register_vers_node (const char *name,
6857130561Sobrien			 struct bfd_elf_version_tree *version,
6858130561Sobrien			 struct bfd_elf_version_deps *deps)
685933965Sjdp{
686033965Sjdp  struct bfd_elf_version_tree *t, **pp;
686133965Sjdp  struct bfd_elf_version_expr *e1;
686233965Sjdp
686389857Sobrien  if (name == NULL)
686489857Sobrien    name = "";
686589857Sobrien
686689857Sobrien  if ((name[0] == '\0' && lang_elf_version_info != NULL)
686789857Sobrien      || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
686889857Sobrien    {
6869218822Sdim      einfo (_("%X%P: anonymous version tag cannot be combined"
6870218822Sdim	       " with other version tags\n"));
6871130561Sobrien      free (version);
687289857Sobrien      return;
687389857Sobrien    }
687489857Sobrien
687533965Sjdp  /* Make sure this node has a unique name.  */
687633965Sjdp  for (t = lang_elf_version_info; t != NULL; t = t->next)
687733965Sjdp    if (strcmp (t->name, name) == 0)
687860484Sobrien      einfo (_("%X%P: duplicate version tag `%s'\n"), name);
687933965Sjdp
6880130561Sobrien  lang_finalize_version_expr_head (&version->globals);
6881130561Sobrien  lang_finalize_version_expr_head (&version->locals);
6882130561Sobrien
688333965Sjdp  /* Check the global and local match names, and make sure there
688433965Sjdp     aren't any duplicates.  */
688533965Sjdp
6886130561Sobrien  for (e1 = version->globals.list; e1 != NULL; e1 = e1->next)
688733965Sjdp    {
688833965Sjdp      for (t = lang_elf_version_info; t != NULL; t = t->next)
688933965Sjdp	{
689033965Sjdp	  struct bfd_elf_version_expr *e2;
689133965Sjdp
6892130561Sobrien	  if (t->locals.htab && e1->symbol)
6893130561Sobrien	    {
6894130561Sobrien	      e2 = htab_find (t->locals.htab, e1);
6895130561Sobrien	      while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
6896130561Sobrien		{
6897130561Sobrien		  if (e1->mask == e2->mask)
6898218822Sdim		    einfo (_("%X%P: duplicate expression `%s'"
6899218822Sdim			     " in version information\n"), e1->symbol);
6900130561Sobrien		  e2 = e2->next;
6901130561Sobrien		}
6902130561Sobrien	    }
6903130561Sobrien	  else if (!e1->symbol)
6904130561Sobrien	    for (e2 = t->locals.remaining; e2 != NULL; e2 = e2->next)
6905218822Sdim	      if (strcmp (e1->pattern, e2->pattern) == 0
6906218822Sdim		  && e1->mask == e2->mask)
6907218822Sdim		einfo (_("%X%P: duplicate expression `%s'"
6908218822Sdim			 " in version information\n"), e1->pattern);
690933965Sjdp	}
691033965Sjdp    }
691133965Sjdp
6912130561Sobrien  for (e1 = version->locals.list; e1 != NULL; e1 = e1->next)
691333965Sjdp    {
691433965Sjdp      for (t = lang_elf_version_info; t != NULL; t = t->next)
691533965Sjdp	{
691633965Sjdp	  struct bfd_elf_version_expr *e2;
691733965Sjdp
6918130561Sobrien	  if (t->globals.htab && e1->symbol)
6919130561Sobrien	    {
6920130561Sobrien	      e2 = htab_find (t->globals.htab, e1);
6921130561Sobrien	      while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
6922130561Sobrien		{
6923130561Sobrien		  if (e1->mask == e2->mask)
6924218822Sdim		    einfo (_("%X%P: duplicate expression `%s'"
6925218822Sdim			     " in version information\n"),
6926130561Sobrien			   e1->symbol);
6927130561Sobrien		  e2 = e2->next;
6928130561Sobrien		}
6929130561Sobrien	    }
6930130561Sobrien	  else if (!e1->symbol)
6931130561Sobrien	    for (e2 = t->globals.remaining; e2 != NULL; e2 = e2->next)
6932218822Sdim	      if (strcmp (e1->pattern, e2->pattern) == 0
6933218822Sdim		  && e1->mask == e2->mask)
6934218822Sdim		einfo (_("%X%P: duplicate expression `%s'"
6935218822Sdim			 " in version information\n"), e1->pattern);
693633965Sjdp	}
693733965Sjdp    }
693833965Sjdp
693933965Sjdp  version->deps = deps;
694033965Sjdp  version->name = name;
694189857Sobrien  if (name[0] != '\0')
694289857Sobrien    {
694389857Sobrien      ++version_index;
694489857Sobrien      version->vernum = version_index;
694589857Sobrien    }
694689857Sobrien  else
694789857Sobrien    version->vernum = 0;
694833965Sjdp
694933965Sjdp  for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next)
695033965Sjdp    ;
695133965Sjdp  *pp = version;
695233965Sjdp}
695333965Sjdp
695433965Sjdp/* This is called when we see a version dependency.  */
695533965Sjdp
695633965Sjdpstruct bfd_elf_version_deps *
6957130561Sobrienlang_add_vers_depend (struct bfd_elf_version_deps *list, const char *name)
695833965Sjdp{
695933965Sjdp  struct bfd_elf_version_deps *ret;
696033965Sjdp  struct bfd_elf_version_tree *t;
696133965Sjdp
6962130561Sobrien  ret = xmalloc (sizeof *ret);
696333965Sjdp  ret->next = list;
696433965Sjdp
696533965Sjdp  for (t = lang_elf_version_info; t != NULL; t = t->next)
696633965Sjdp    {
696733965Sjdp      if (strcmp (t->name, name) == 0)
696833965Sjdp	{
696933965Sjdp	  ret->version_needed = t;
697033965Sjdp	  return ret;
697133965Sjdp	}
697233965Sjdp    }
697333965Sjdp
697460484Sobrien  einfo (_("%X%P: unable to find version dependency `%s'\n"), name);
697533965Sjdp
697633965Sjdp  return ret;
697733965Sjdp}
697860484Sobrien
697960484Sobrienstatic void
6980130561Sobrienlang_do_version_exports_section (void)
698160484Sobrien{
698260484Sobrien  struct bfd_elf_version_expr *greg = NULL, *lreg;
698360484Sobrien
698460484Sobrien  LANG_FOR_EACH_INPUT_STATEMENT (is)
698560484Sobrien    {
698660484Sobrien      asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports");
698760484Sobrien      char *contents, *p;
698860484Sobrien      bfd_size_type len;
698960484Sobrien
699060484Sobrien      if (sec == NULL)
6991104834Sobrien	continue;
699260484Sobrien
6993218822Sdim      len = sec->size;
699460484Sobrien      contents = xmalloc (len);
699560484Sobrien      if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
699689857Sobrien	einfo (_("%X%P: unable to read .exports section contents\n"), sec);
699760484Sobrien
699860484Sobrien      p = contents;
699977298Sobrien      while (p < contents + len)
700060484Sobrien	{
7001218822Sdim	  greg = lang_new_vers_pattern (greg, p, NULL, FALSE);
700260484Sobrien	  p = strchr (p, '\0') + 1;
700360484Sobrien	}
700460484Sobrien
700560484Sobrien      /* Do not free the contents, as we used them creating the regex.  */
700660484Sobrien
700760484Sobrien      /* Do not include this section in the link.  */
7008218822Sdim      sec->flags |= SEC_EXCLUDE | SEC_KEEP;
700960484Sobrien    }
701060484Sobrien
7011218822Sdim  lreg = lang_new_vers_pattern (NULL, "*", NULL, FALSE);
701260484Sobrien  lang_register_vers_node (command_line.version_exports_section,
701360484Sobrien			   lang_new_vers_node (greg, lreg), NULL);
701460484Sobrien}
701577298Sobrien
701677298Sobrienvoid
7017130561Sobrienlang_add_unique (const char *name)
701877298Sobrien{
701977298Sobrien  struct unique_sections *ent;
702077298Sobrien
702177298Sobrien  for (ent = unique_section_list; ent; ent = ent->next)
702277298Sobrien    if (strcmp (ent->name, name) == 0)
702377298Sobrien      return;
702477298Sobrien
7025130561Sobrien  ent = xmalloc (sizeof *ent);
702677298Sobrien  ent->name = xstrdup (name);
702777298Sobrien  ent->next = unique_section_list;
702877298Sobrien  unique_section_list = ent;
702977298Sobrien}
7030218822Sdim
7031218822Sdim/* Append the list of dynamic symbols to the existing one.  */
7032218822Sdim
7033218822Sdimvoid
7034218822Sdimlang_append_dynamic_list (struct bfd_elf_version_expr *dynamic)
7035218822Sdim{
7036218822Sdim  if (link_info.dynamic_list)
7037218822Sdim    {
7038218822Sdim      struct bfd_elf_version_expr *tail;
7039218822Sdim      for (tail = dynamic; tail->next != NULL; tail = tail->next)
7040218822Sdim	;
7041218822Sdim      tail->next = link_info.dynamic_list->head.list;
7042218822Sdim      link_info.dynamic_list->head.list = dynamic;
7043218822Sdim    }
7044218822Sdim  else
7045218822Sdim    {
7046218822Sdim      struct bfd_elf_dynamic_list *d;
7047218822Sdim
7048218822Sdim      d = xcalloc (1, sizeof *d);
7049218822Sdim      d->head.list = dynamic;
7050218822Sdim      d->match = lang_vers_match;
7051218822Sdim      link_info.dynamic_list = d;
7052218822Sdim    }
7053218822Sdim}
7054218822Sdim
7055218822Sdim/* Append the list of C++ typeinfo dynamic symbols to the existing
7056218822Sdim   one.  */
7057218822Sdim
7058218822Sdimvoid
7059218822Sdimlang_append_dynamic_list_cpp_typeinfo (void)
7060218822Sdim{
7061218822Sdim  const char * symbols [] =
7062218822Sdim    {
7063218822Sdim      "typeinfo name for*",
7064218822Sdim      "typeinfo for*"
7065218822Sdim    };
7066218822Sdim  struct bfd_elf_version_expr *dynamic = NULL;
7067218822Sdim  unsigned int i;
7068218822Sdim
7069218822Sdim  for (i = 0; i < ARRAY_SIZE (symbols); i++)
7070218822Sdim    dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++",
7071218822Sdim				     FALSE);
7072218822Sdim
7073218822Sdim  lang_append_dynamic_list (dynamic);
7074218822Sdim}
7075218822Sdim
7076218822Sdim/* Append the list of C++ operator new and delete dynamic symbols to the
7077218822Sdim   existing one.  */
7078218822Sdim
7079218822Sdimvoid
7080218822Sdimlang_append_dynamic_list_cpp_new (void)
7081218822Sdim{
7082218822Sdim  const char * symbols [] =
7083218822Sdim    {
7084218822Sdim      "operator new*",
7085218822Sdim      "operator delete*"
7086218822Sdim    };
7087218822Sdim  struct bfd_elf_version_expr *dynamic = NULL;
7088218822Sdim  unsigned int i;
7089218822Sdim
7090218822Sdim  for (i = 0; i < ARRAY_SIZE (symbols); i++)
7091218822Sdim    dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++",
7092218822Sdim				     FALSE);
7093218822Sdim
7094218822Sdim  lang_append_dynamic_list (dynamic);
7095218822Sdim}
7096