OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [emultempl/] [xtensaelf.em] - Blame information for rev 268

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 khays
# This shell script emits a C file. -*- C -*-
2
#   Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3
#   Free Software Foundation, Inc.
4
#
5
# This file is part of the GNU Binutils.
6
#
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
# MA 02110-1301, USA.
21
#
22
 
23
# This file is sourced from elf32.em, and defines extra xtensa-elf
24
# specific routines.
25
#
26
fragment <
27
 
28
#include 
29
#include "../bfd/elf-bfd.h"
30
#include "../bfd/libbfd.h"
31
#include "elf/xtensa.h"
32
#include "bfd.h"
33
 
34
/* Provide default values for new configuration settings.  */
35
#ifndef XSHAL_ABI
36
#define XSHAL_ABI 0
37
#endif
38
 
39
static void xtensa_wild_group_interleave (lang_statement_union_type *);
40
static void xtensa_colocate_output_literals (lang_statement_union_type *);
41
static void xtensa_strip_inconsistent_linkonce_sections
42
  (lang_statement_list_type *);
43
 
44
 
45
/* This number is irrelevant until we turn on use_literal_pages */
46
static bfd_vma xtensa_page_power = 12; /* 4K pages.  */
47
 
48
/* To force a page break between literals and text, change
49
   xtensa_use_literal_pages to "TRUE".  */
50
static bfd_boolean xtensa_use_literal_pages = FALSE;
51
 
52
#define EXTRA_VALIDATION 0
53
 
54
 
55
static char *
56
elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
57
                          char **argv ATTRIBUTE_UNUSED)
58
{
59
  if (XCHAL_HAVE_BE)
60
    return "${BIG_OUTPUT_FORMAT}";
61
  else
62
    return "${LITTLE_OUTPUT_FORMAT}";
63
}
64
 
65
 
66
static void
67
elf_xtensa_before_parse (void)
68
{
69
  /* Just call the default hook.... Tensilica's version of this function
70
     does some other work that isn't relevant here.  */
71
  gld${EMULATION_NAME}_before_parse ();
72
}
73
 
74
 
75
static void
76
remove_section (bfd *abfd, asection *os)
77
{
78
  asection **spp;
79
  for (spp = &abfd->sections; *spp; spp = &(*spp)->next)
80
    if (*spp == os)
81
      {
82
        *spp = os->next;
83
        os->owner->section_count--;
84
        break;
85
      }
86
}
87
 
88
 
89
static bfd_boolean
90
replace_insn_sec_with_prop_sec (bfd *abfd,
91
                                const char *insn_sec_name,
92
                                const char *prop_sec_name,
93
                                char **error_message)
94
{
95
  asection *insn_sec;
96
  asection *prop_sec;
97
  bfd_byte *prop_contents = NULL;
98
  bfd_byte *insn_contents = NULL;
99
  unsigned entry_count;
100
  unsigned entry;
101
  Elf_Internal_Shdr *rel_hdr;
102
  Elf_Internal_Rela *internal_relocs = NULL;
103
  unsigned reloc_count;
104
 
105
  *error_message = "";
106
  insn_sec = bfd_get_section_by_name (abfd, insn_sec_name);
107
  if (insn_sec == NULL)
108
    return TRUE;
109
  entry_count = insn_sec->size / 8;
110
 
111
  prop_sec = bfd_get_section_by_name (abfd, prop_sec_name);
112
  if (prop_sec != NULL && insn_sec != NULL)
113
    {
114
      *error_message = _("file already has property tables");
115
      return FALSE;
116
    }
117
 
118
  if (insn_sec->size != 0)
119
    {
120
      insn_contents = (bfd_byte *) bfd_malloc (insn_sec->size);
121
      if (insn_contents == NULL)
122
        {
123
          *error_message = _("out of memory");
124
          goto cleanup;
125
        }
126
      if (! bfd_get_section_contents (abfd, insn_sec, insn_contents,
127
                                      (file_ptr) 0, insn_sec->size))
128
        {
129
          *error_message = _("failed to read section contents");
130
          goto cleanup;
131
        }
132
    }
133
 
134
  /* Create a property table section for it.  */
135
  prop_sec_name = strdup (prop_sec_name);
136
  prop_sec = bfd_make_section_with_flags
137
    (abfd, prop_sec_name, bfd_get_section_flags (abfd, insn_sec));
138
  if (prop_sec == NULL
139
      || ! bfd_set_section_alignment (abfd, prop_sec, 2))
140
    {
141
      *error_message = _("could not create new section");
142
      goto cleanup;
143
    }
144
 
145
  prop_sec->size = entry_count * 12;
146
  prop_contents = (bfd_byte *) bfd_zalloc (abfd, prop_sec->size);
147
  elf_section_data (prop_sec)->this_hdr.contents = prop_contents;
148
 
149
  /* The entry size and size must be set to allow the linker to compute
150
     the number of relocations since it does not use reloc_count.  */
151
  rel_hdr = _bfd_elf_single_rel_hdr (prop_sec);
152
  rel_hdr->sh_entsize = sizeof (Elf32_External_Rela);
153
  rel_hdr->sh_size = _bfd_elf_single_rel_hdr (insn_sec)->sh_size;
154
 
155
  if (prop_contents == NULL && prop_sec->size != 0)
156
    {
157
      *error_message = _("could not allocate section contents");
158
      goto cleanup;
159
    }
160
 
161
  /* Read the relocations.  */
162
  reloc_count = insn_sec->reloc_count;
163
  if (reloc_count != 0)
164
    {
165
      /* If there is already an internal_reloc, then save it so that the
166
         read_relocs function freshly allocates a copy.  */
167
      Elf_Internal_Rela *saved_relocs = elf_section_data (insn_sec)->relocs;
168
 
169
      elf_section_data (insn_sec)->relocs = NULL;
170
      internal_relocs =
171
        _bfd_elf_link_read_relocs (abfd, insn_sec, NULL, NULL, FALSE);
172
      elf_section_data (insn_sec)->relocs = saved_relocs;
173
 
174
      if (internal_relocs == NULL)
175
        {
176
          *error_message = _("out of memory");
177
          goto cleanup;
178
        }
179
    }
180
 
181
  /* Create a relocation section for the property section.  */
182
  if (internal_relocs != NULL)
183
    {
184
      elf_section_data (prop_sec)->relocs = internal_relocs;
185
      prop_sec->reloc_count = reloc_count;
186
    }
187
 
188
  /* Now copy each insn table entry to the prop table entry with
189
     appropriate flags.  */
190
  for (entry = 0; entry < entry_count; ++entry)
191
    {
192
      unsigned value;
193
      unsigned flags = (XTENSA_PROP_INSN | XTENSA_PROP_NO_TRANSFORM
194
                        | XTENSA_PROP_INSN_NO_REORDER);
195
      value = bfd_get_32 (abfd, insn_contents + entry * 8 + 0);
196
      bfd_put_32 (abfd, value, prop_contents + entry * 12 + 0);
197
      value = bfd_get_32 (abfd, insn_contents + entry * 8 + 4);
198
      bfd_put_32 (abfd, value, prop_contents + entry * 12 + 4);
199
      bfd_put_32 (abfd, flags, prop_contents + entry * 12 + 8);
200
    }
201
 
202
  /* Now copy all of the relocations.  Change offsets for the
203
     instruction table section to offsets in the property table
204
     section.  */
205
  if (internal_relocs)
206
    {
207
      unsigned i;
208
 
209
      for (i = 0; i < reloc_count; i++)
210
        {
211
          Elf_Internal_Rela *rela;
212
          unsigned r_offset;
213
 
214
          rela = &internal_relocs[i];
215
 
216
          /* If this relocation is to the .xt.insn section,
217
             change the section number and the offset.  */
218
          r_offset = rela->r_offset;
219
          r_offset += 4 * (r_offset / 8);
220
          rela->r_offset = r_offset;
221
        }
222
    }
223
 
224
  remove_section (abfd, insn_sec);
225
 
226
  if (insn_contents)
227
    free (insn_contents);
228
 
229
  return TRUE;
230
 
231
 cleanup:
232
  if (prop_sec && prop_sec->owner)
233
    remove_section (abfd, prop_sec);
234
  if (insn_contents)
235
    free (insn_contents);
236
  if (internal_relocs)
237
    free (internal_relocs);
238
 
239
  return FALSE;
240
}
241
 
242
 
243
#define PROP_SEC_BASE_NAME ".xt.prop"
244
#define INSN_SEC_BASE_NAME ".xt.insn"
245
#define LINKONCE_SEC_OLD_TEXT_BASE_NAME ".gnu.linkonce.x."
246
 
247
 
248
static void
249
replace_instruction_table_sections (bfd *abfd, asection *sec)
250
{
251
  char *message = "";
252
  const char *insn_sec_name = NULL;
253
  char *prop_sec_name = NULL;
254
  char *owned_prop_sec_name = NULL;
255
  const char *sec_name;
256
 
257
  sec_name = bfd_get_section_name (abfd, sec);
258
  if (strcmp (sec_name, INSN_SEC_BASE_NAME) == 0)
259
    {
260
      insn_sec_name = INSN_SEC_BASE_NAME;
261
      prop_sec_name = PROP_SEC_BASE_NAME;
262
    }
263
  else if (CONST_STRNEQ (sec_name, LINKONCE_SEC_OLD_TEXT_BASE_NAME))
264
    {
265
      insn_sec_name = sec_name;
266
      owned_prop_sec_name = (char *) xmalloc (strlen (sec_name) + 20);
267
      prop_sec_name = owned_prop_sec_name;
268
      strcpy (prop_sec_name, ".gnu.linkonce.prop.t.");
269
      strcat (prop_sec_name,
270
              sec_name + strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME));
271
    }
272
  if (insn_sec_name != NULL)
273
    {
274
      if (! replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name,
275
                                            &message))
276
        {
277
          einfo (_("%P: warning: failed to convert %s table in %B (%s); subsequent disassembly may be incomplete\n"),
278
                 insn_sec_name, abfd, message);
279
        }
280
    }
281
  if (owned_prop_sec_name)
282
    free (owned_prop_sec_name);
283
}
284
 
285
 
286
/* This is called after all input sections have been opened to convert
287
   instruction tables (.xt.insn, gnu.linkonce.x.*) tables into property
288
   tables (.xt.prop) before any section placement.  */
289
 
290
static void
291
elf_xtensa_after_open (void)
292
{
293
  /* First call the ELF version.  */
294
  gld${EMULATION_NAME}_after_open ();
295
 
296
  /* Now search the input files looking for instruction table sections.  */
297
  LANG_FOR_EACH_INPUT_STATEMENT (f)
298
    {
299
      asection *sec = f->the_bfd->sections;
300
      asection *next_sec;
301
 
302
      /* Do not use bfd_map_over_sections here since we are removing
303
         sections as we iterate.  */
304
      while (sec != NULL)
305
        {
306
          next_sec = sec->next;
307
          replace_instruction_table_sections (f->the_bfd, sec);
308
          sec = next_sec;
309
        }
310
    }
311
}
312
 
313
 
314
static bfd_boolean
315
xt_config_info_unpack_and_check (char *data,
316
                                 bfd_boolean *pmismatch,
317
                                 char **pmsg)
318
{
319
  char *d, *key;
320
  unsigned num;
321
 
322
  *pmismatch = FALSE;
323
 
324
  d = data;
325
  while (*d)
326
    {
327
      key = d;
328
      d = strchr (d, '=');
329
      if (! d)
330
        goto error;
331
 
332
      /* Overwrite the equal sign.  */
333
      *d++ = 0;
334
 
335
      /* Check if this is a quoted string or a number.  */
336
      if (*d == '"')
337
        {
338
          /* No string values are currently checked by LD;
339
             just skip over the quotes.  */
340
          d++;
341
          d = strchr (d, '"');
342
          if (! d)
343
            goto error;
344
          /* Overwrite the trailing quote.  */
345
          *d++ = 0;
346
        }
347
      else
348
        {
349
          if (*d == 0)
350
            goto error;
351
          num = strtoul (d, &d, 0);
352
 
353
          if (! strcmp (key, "ABI"))
354
            {
355
              if (num != XSHAL_ABI)
356
                {
357
                  *pmismatch = TRUE;
358
                  *pmsg = "ABI does not match";
359
                }
360
            }
361
          else if (! strcmp (key, "USE_ABSOLUTE_LITERALS"))
362
            {
363
              if (num != XSHAL_USE_ABSOLUTE_LITERALS)
364
                {
365
                  *pmismatch = TRUE;
366
                  *pmsg = "incompatible use of the Extended L32R option";
367
                }
368
            }
369
        }
370
 
371
      if (*d++ != '\n')
372
        goto error;
373
    }
374
 
375
  return TRUE;
376
 
377
 error:
378
  return FALSE;
379
}
380
 
381
 
382
#define XTINFO_NAME "Xtensa_Info"
383
#define XTINFO_NAMESZ 12
384
#define XTINFO_TYPE 1
385
 
386
static void
387
check_xtensa_info (bfd *abfd, asection *info_sec)
388
{
389
  char *data, *errmsg = "";
390
  bfd_boolean mismatch;
391
 
392
  data = xmalloc (info_sec->size);
393
  if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec->size))
394
    einfo (_("%F%P:%B: cannot read contents of section %A\n"), abfd, info_sec);
395
 
396
  if (info_sec->size > 24
397
      && info_sec->size >= 24 + bfd_get_32 (abfd, data + 4)
398
      && bfd_get_32 (abfd, data + 0) == XTINFO_NAMESZ
399
      && bfd_get_32 (abfd, data + 8) == XTINFO_TYPE
400
      && strcmp (data + 12, XTINFO_NAME) == 0
401
      && xt_config_info_unpack_and_check (data + 12 + XTINFO_NAMESZ,
402
                                          &mismatch, &errmsg))
403
    {
404
      if (mismatch)
405
        einfo (_("%P:%B: warning: incompatible Xtensa configuration (%s)\n"),
406
               abfd, errmsg);
407
    }
408
  else
409
    einfo (_("%P:%B: warning: cannot parse .xtensa.info section\n"), abfd);
410
 
411
  free (data);
412
}
413
 
414
 
415
/* This is called after the sections have been attached to output
416
   sections, but before any sizes or addresses have been set.  */
417
 
418
static void
419
elf_xtensa_before_allocation (void)
420
{
421
  asection *info_sec, *first_info_sec;
422
  bfd *first_bfd;
423
  bfd_boolean is_big_endian = XCHAL_HAVE_BE;
424
 
425
  /* Check that the output endianness matches the Xtensa
426
     configuration.  The BFD library always includes both big and
427
     little endian target vectors for Xtensa, but it only supports the
428
     detailed instruction encode/decode operations (such as are
429
     required to process relocations) for the selected Xtensa
430
     configuration.  */
431
 
432
  if (is_big_endian
433
      && link_info.output_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
434
    {
435
      einfo (_("%F%P: little endian output does not match "
436
               "Xtensa configuration\n"));
437
    }
438
  if (!is_big_endian
439
      && link_info.output_bfd->xvec->byteorder == BFD_ENDIAN_BIG)
440
    {
441
      einfo (_("%F%P: big endian output does not match "
442
               "Xtensa configuration\n"));
443
    }
444
 
445
  /* Keep track of the first input .xtensa.info section, and as a fallback,
446
     the first input bfd where a .xtensa.info section could be created.
447
     After the input .xtensa.info has been checked, the contents of the
448
     first one will be replaced with the output .xtensa.info table.  */
449
  first_info_sec = 0;
450
  first_bfd = 0;
451
 
452
  LANG_FOR_EACH_INPUT_STATEMENT (f)
453
    {
454
      /* Check that the endianness for each input file matches the output.
455
         The merge_private_bfd_data hook has already reported any mismatches
456
         as errors, but those errors are not fatal.  At this point, we
457
         cannot go any further if there are any mismatches.  */
458
      if ((is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
459
          || (!is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_BIG))
460
        einfo (_("%F%P: cross-endian linking for %B not supported\n"),
461
               f->the_bfd);
462
 
463
      if (! first_bfd)
464
        first_bfd = f->the_bfd;
465
 
466
      info_sec = bfd_get_section_by_name (f->the_bfd, ".xtensa.info");
467
      if (! info_sec)
468
        continue;
469
 
470
      if (! first_info_sec)
471
        first_info_sec = info_sec;
472
 
473
      /* Unpack the .xtensa.info section and check it against the current
474
         Xtensa configuration.  */
475
      check_xtensa_info (f->the_bfd, info_sec);
476
 
477
      /* Do not include this copy of .xtensa.info in the output.  */
478
      info_sec->size = 0;
479
      info_sec->flags |= SEC_EXCLUDE;
480
    }
481
 
482
  /* Reuse the first .xtensa.info input section to hold the output
483
     .xtensa.info; or, if none were found, create a new section in the
484
     first input bfd (assuming there is one).  */
485
  info_sec = first_info_sec;
486
  if (! info_sec && first_bfd)
487
    {
488
      info_sec = bfd_make_section_with_flags (first_bfd, ".xtensa.info",
489
                                              SEC_HAS_CONTENTS | SEC_READONLY);
490
      if (! info_sec)
491
        einfo (_("%F%P: failed to create .xtensa.info section\n"));
492
    }
493
  if (info_sec)
494
    {
495
      int xtensa_info_size;
496
      char *data;
497
 
498
      info_sec->flags &= ~SEC_EXCLUDE;
499
      info_sec->flags |= SEC_IN_MEMORY;
500
 
501
      data = xmalloc (100);
502
      sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
503
               XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI);
504
      xtensa_info_size = strlen (data) + 1;
505
 
506
      /* Add enough null terminators to pad to a word boundary.  */
507
      do
508
        data[xtensa_info_size++] = 0;
509
      while ((xtensa_info_size & 3) != 0);
510
 
511
      info_sec->size = 12 + XTINFO_NAMESZ + xtensa_info_size;
512
      info_sec->contents = xmalloc (info_sec->size);
513
      bfd_put_32 (info_sec->owner, XTINFO_NAMESZ, info_sec->contents + 0);
514
      bfd_put_32 (info_sec->owner, xtensa_info_size, info_sec->contents + 4);
515
      bfd_put_32 (info_sec->owner, XTINFO_TYPE, info_sec->contents + 8);
516
      memcpy (info_sec->contents + 12, XTINFO_NAME, XTINFO_NAMESZ);
517
      memcpy (info_sec->contents + 12 + XTINFO_NAMESZ, data, xtensa_info_size);
518
      free (data);
519
    }
520
 
521
  /* Enable relaxation by default if the "--no-relax" option was not
522
     specified.  This is done here instead of in the before_parse hook
523
     because there is a check in main() to prohibit use of --relax and
524
     -r together and that combination should be allowed for Xtensa.  */
525
  if (RELAXATION_DISABLED_BY_DEFAULT)
526
    ENABLE_RELAXATION;
527
 
528
  xtensa_strip_inconsistent_linkonce_sections (stat_ptr);
529
 
530
  gld${EMULATION_NAME}_before_allocation ();
531
 
532
  xtensa_wild_group_interleave (stat_ptr->head);
533
 
534
  if (RELAXATION_ENABLED)
535
    xtensa_colocate_output_literals (stat_ptr->head);
536
 
537
  /* TBD: We need to force the page alignments to here and only do
538
     them as needed for the entire output section.  Finally, if this
539
     is a relocatable link then we need to add alignment notes so
540
     that the literals can be separated later.  */
541
}
542
 
543
 
544
typedef struct wildcard_list section_name_list;
545
 
546
typedef struct reloc_deps_e_t reloc_deps_e;
547
typedef struct reloc_deps_section_t reloc_deps_section;
548
typedef struct reloc_deps_graph_t reloc_deps_graph;
549
 
550
 
551
struct reloc_deps_e_t
552
{
553
  asection *src; /* Contains l32rs.  */
554
  asection *tgt; /* Contains literals.  */
555
  reloc_deps_e *next;
556
};
557
 
558
/* Place these in the userdata field.  */
559
struct reloc_deps_section_t
560
{
561
  reloc_deps_e *preds;
562
  reloc_deps_e *succs;
563
  bfd_boolean is_only_literal;
564
};
565
 
566
 
567
struct reloc_deps_graph_t
568
{
569
  size_t count;
570
  size_t size;
571
  asection **sections;
572
};
573
 
574
static void xtensa_layout_wild
575
  (const reloc_deps_graph *, lang_wild_statement_type *);
576
 
577
typedef void (*deps_callback_t) (asection *, /* src_sec */
578
                                 bfd_vma,    /* src_offset */
579
                                 asection *, /* target_sec */
580
                                 bfd_vma,    /* target_offset */
581
                                 void *);    /* closure */
582
 
583
extern bfd_boolean xtensa_callback_required_dependence
584
  (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);
585
static void xtensa_ldlang_clear_addresses (lang_statement_union_type *);
586
static bfd_boolean ld_local_file_relocations_fit
587
  (lang_statement_union_type *, const reloc_deps_graph *);
588
static bfd_vma ld_assign_relative_paged_dot
589
  (bfd_vma, lang_statement_union_type *, const reloc_deps_graph *,
590
   bfd_boolean);
591
static bfd_vma ld_xtensa_insert_page_offsets
592
  (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean);
593
#if EXTRA_VALIDATION
594
static size_t ld_count_children (lang_statement_union_type *);
595
#endif
596
 
597
extern lang_statement_list_type constructor_list;
598
 
599
static reloc_deps_section *
600
xtensa_get_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
601
                         asection *sec)
602
{
603
  /* We have a separate function for this so that
604
     we could in the future keep a completely independent
605
     structure that maps a section to its dependence edges.
606
     For now, we place these in the sec->userdata field.  */
607
  reloc_deps_section *sec_deps = sec->userdata;
608
  return sec_deps;
609
}
610
 
611
static void
612
xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
613
                         asection *sec,
614
                         reloc_deps_section *deps_section)
615
{
616
  sec->userdata = deps_section;
617
}
618
 
619
 
620
/* This is used to keep a list of all of the sections participating in
621
   the graph so we can clean them up quickly.  */
622
 
623
static void
624
xtensa_append_section_deps (reloc_deps_graph *deps, asection *sec)
625
{
626
  if (deps->size <= deps->count)
627
    {
628
      asection **new_sections;
629
      size_t i;
630
      size_t new_size;
631
 
632
      new_size = deps->size * 2;
633
      if (new_size == 0)
634
        new_size = 20;
635
 
636
      new_sections = xmalloc (sizeof (asection *) * new_size);
637
      memset (new_sections, 0, sizeof (asection *) * new_size);
638
      for (i = 0; i < deps->count; i++)
639
        {
640
          new_sections[i] = deps->sections[i];
641
        }
642
      if (deps->sections != NULL)
643
        free (deps->sections);
644
      deps->sections = new_sections;
645
      deps->size = new_size;
646
    }
647
  deps->sections[deps->count] = sec;
648
  deps->count++;
649
}
650
 
651
 
652
static void
653
free_reloc_deps_graph (reloc_deps_graph *deps)
654
{
655
  size_t i;
656
  for (i = 0; i < deps->count; i++)
657
    {
658
      asection *sec = deps->sections[i];
659
      reloc_deps_section *sec_deps;
660
      sec_deps = xtensa_get_section_deps (deps, sec);
661
      if (sec_deps)
662
        {
663
          reloc_deps_e *next;
664
          while (sec_deps->succs != NULL)
665
            {
666
              next = sec_deps->succs->next;
667
              free (sec_deps->succs);
668
              sec_deps->succs = next;
669
            }
670
 
671
          while (sec_deps->preds != NULL)
672
            {
673
              next = sec_deps->preds->next;
674
              free (sec_deps->preds);
675
              sec_deps->preds = next;
676
            }
677
          free (sec_deps);
678
        }
679
      xtensa_set_section_deps (deps, sec, NULL);
680
    }
681
  if (deps->sections)
682
    free (deps->sections);
683
 
684
  free (deps);
685
}
686
 
687
 
688
static bfd_boolean
689
section_is_source (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
690
                   lang_statement_union_type *s)
691
{
692
  asection *sec;
693
  const reloc_deps_section *sec_deps;
694
 
695
  if (s->header.type != lang_input_section_enum)
696
    return FALSE;
697
  sec = s->input_section.section;
698
 
699
  sec_deps = xtensa_get_section_deps (deps, sec);
700
  return sec_deps && sec_deps->succs != NULL;
701
}
702
 
703
 
704
static bfd_boolean
705
section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
706
                   lang_statement_union_type *s)
707
{
708
  asection *sec;
709
  const reloc_deps_section *sec_deps;
710
 
711
  if (s->header.type != lang_input_section_enum)
712
    return FALSE;
713
  sec = s->input_section.section;
714
 
715
  sec_deps = xtensa_get_section_deps (deps, sec);
716
  return sec_deps && sec_deps->preds != NULL;
717
}
718
 
719
 
720
static bfd_boolean
721
section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
722
                             lang_statement_union_type *s)
723
{
724
  return (section_is_source (deps, s)
725
          || section_is_target (deps, s));
726
}
727
 
728
 
729
typedef struct xtensa_ld_iter_stack_t xtensa_ld_iter_stack;
730
typedef struct xtensa_ld_iter_t xtensa_ld_iter;
731
 
732
struct xtensa_ld_iter_t
733
{
734
  lang_statement_union_type *parent;    /* Parent of the list.  */
735
  lang_statement_list_type *l;          /* List that holds it.  */
736
  lang_statement_union_type **loc;      /* Place in the list.  */
737
};
738
 
739
struct xtensa_ld_iter_stack_t
740
{
741
  xtensa_ld_iter iterloc;               /* List that hold it.  */
742
 
743
  xtensa_ld_iter_stack *next;           /* Next in the stack.  */
744
  xtensa_ld_iter_stack *prev;           /* Back pointer for stack.  */
745
};
746
 
747
 
748
static void
749
ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current)
750
{
751
  lang_statement_union_type *to_next;
752
  lang_statement_union_type *current_next;
753
  lang_statement_union_type **e;
754
 
755
#if EXTRA_VALIDATION
756
  size_t old_to_count, new_to_count;
757
  size_t old_current_count, new_current_count;
758
#endif
759
 
760
  if (to == current)
761
    return;
762
 
763
#if EXTRA_VALIDATION
764
  old_to_count = ld_count_children (to->parent);
765
  old_current_count = ld_count_children (current->parent);
766
#endif
767
 
768
  to_next = *(to->loc);
769
  current_next = (*current->loc)->header.next;
770
 
771
  *(to->loc) = *(current->loc);
772
 
773
  *(current->loc) = current_next;
774
  (*(to->loc))->header.next = to_next;
775
 
776
  /* reset "to" list tail */
777
  for (e = &to->l->head; *e != NULL; e = &(*e)->header.next)
778
    ;
779
  to->l->tail = e;
780
 
781
  /* reset "current" list tail */
782
  for (e = ¤t->l->head; *e != NULL; e = &(*e)->header.next)
783
    ;
784
  current->l->tail = e;
785
 
786
#if EXTRA_VALIDATION
787
  new_to_count = ld_count_children (to->parent);
788
  new_current_count = ld_count_children (current->parent);
789
 
790
  ASSERT ((old_to_count + old_current_count)
791
          == (new_to_count + new_current_count));
792
#endif
793
}
794
 
795
 
796
/* Can only be called with lang_statements that have lists.  Returns
797
   FALSE if the list is empty.  */
798
 
799
static bfd_boolean
800
iter_stack_empty (xtensa_ld_iter_stack **stack_p)
801
{
802
  return *stack_p == NULL;
803
}
804
 
805
 
806
static bfd_boolean
807
iter_stack_push (xtensa_ld_iter_stack **stack_p,
808
                 lang_statement_union_type *parent)
809
{
810
  xtensa_ld_iter_stack *stack;
811
  lang_statement_list_type *l = NULL;
812
 
813
  switch (parent->header.type)
814
    {
815
    case lang_output_section_statement_enum:
816
      l = &parent->output_section_statement.children;
817
      break;
818
    case lang_wild_statement_enum:
819
      l = &parent->wild_statement.children;
820
      break;
821
    case lang_group_statement_enum:
822
      l = &parent->group_statement.children;
823
      break;
824
    default:
825
      ASSERT (0);
826
      return FALSE;
827
    }
828
 
829
  /* Empty. do not push.  */
830
  if (l->tail == &l->head)
831
    return FALSE;
832
 
833
  stack = xmalloc (sizeof (xtensa_ld_iter_stack));
834
  memset (stack, 0, sizeof (xtensa_ld_iter_stack));
835
  stack->iterloc.parent = parent;
836
  stack->iterloc.l = l;
837
  stack->iterloc.loc = &l->head;
838
 
839
  stack->next = *stack_p;
840
  stack->prev = NULL;
841
  if (*stack_p != NULL)
842
    (*stack_p)->prev = stack;
843
  *stack_p = stack;
844
  return TRUE;
845
}
846
 
847
 
848
static void
849
iter_stack_pop (xtensa_ld_iter_stack **stack_p)
850
{
851
  xtensa_ld_iter_stack *stack;
852
 
853
  stack = *stack_p;
854
 
855
  if (stack == NULL)
856
    {
857
      ASSERT (stack != NULL);
858
      return;
859
    }
860
 
861
  if (stack->next != NULL)
862
    stack->next->prev = NULL;
863
 
864
  *stack_p = stack->next;
865
  free (stack);
866
}
867
 
868
 
869
/* This MUST be called if, during iteration, the user changes the
870
   underlying structure.  It will check for a NULL current and advance
871
   accordingly.  */
872
 
873
static void
874
iter_stack_update (xtensa_ld_iter_stack **stack_p)
875
{
876
  if (!iter_stack_empty (stack_p)
877
      && (*(*stack_p)->iterloc.loc) == NULL)
878
    {
879
      iter_stack_pop (stack_p);
880
 
881
      while (!iter_stack_empty (stack_p)
882
             && ((*(*stack_p)->iterloc.loc)->header.next == NULL))
883
        {
884
          iter_stack_pop (stack_p);
885
        }
886
      if (!iter_stack_empty (stack_p))
887
        (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next;
888
    }
889
}
890
 
891
 
892
static void
893
iter_stack_next (xtensa_ld_iter_stack **stack_p)
894
{
895
  xtensa_ld_iter_stack *stack;
896
  lang_statement_union_type *current;
897
  stack = *stack_p;
898
 
899
  current = *stack->iterloc.loc;
900
  /* If we are on the first element.  */
901
  if (current != NULL)
902
    {
903
      switch (current->header.type)
904
        {
905
        case lang_output_section_statement_enum:
906
        case lang_wild_statement_enum:
907
        case lang_group_statement_enum:
908
          /* If the list if not empty, we are done.  */
909
          if (iter_stack_push (stack_p, *stack->iterloc.loc))
910
            return;
911
          /* Otherwise increment the pointer as normal.  */
912
          break;
913
        default:
914
          break;
915
        }
916
    }
917
 
918
  while (!iter_stack_empty (stack_p)
919
         && ((*(*stack_p)->iterloc.loc)->header.next == NULL))
920
    {
921
      iter_stack_pop (stack_p);
922
    }
923
  if (!iter_stack_empty (stack_p))
924
    (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next;
925
}
926
 
927
 
928
static lang_statement_union_type *
929
iter_stack_current (xtensa_ld_iter_stack **stack_p)
930
{
931
  return *((*stack_p)->iterloc.loc);
932
}
933
 
934
 
935
/* The iter stack is a preorder.  */
936
 
937
static void
938
iter_stack_create (xtensa_ld_iter_stack **stack_p,
939
                   lang_statement_union_type *parent)
940
{
941
  iter_stack_push (stack_p, parent);
942
}
943
 
944
 
945
static void
946
iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, xtensa_ld_iter *front)
947
{
948
  *front = (*stack_p)->iterloc;
949
}
950
 
951
 
952
static void
953
xtensa_colocate_literals (reloc_deps_graph *deps,
954
                          lang_statement_union_type *statement)
955
{
956
  /* Keep a stack of pointers to control iteration through the contours.  */
957
  xtensa_ld_iter_stack *stack = NULL;
958
  xtensa_ld_iter_stack **stack_p = &stack;
959
 
960
  xtensa_ld_iter front;  /* Location where new insertion should occur.  */
961
  xtensa_ld_iter *front_p = NULL;
962
 
963
  xtensa_ld_iter current; /* Location we are checking.  */
964
  xtensa_ld_iter *current_p = NULL;
965
  bfd_boolean in_literals = FALSE;
966
 
967
  if (deps->count == 0)
968
    return;
969
 
970
  iter_stack_create (stack_p, statement);
971
 
972
  while (!iter_stack_empty (stack_p))
973
    {
974
      bfd_boolean skip_increment = FALSE;
975
      lang_statement_union_type *l = iter_stack_current (stack_p);
976
 
977
      switch (l->header.type)
978
        {
979
        case lang_assignment_statement_enum:
980
          /* Any assignment statement should block reordering across it.  */
981
          front_p = NULL;
982
          in_literals = FALSE;
983
          break;
984
 
985
        case lang_input_section_enum:
986
          if (front_p == NULL)
987
            {
988
              in_literals = (section_is_target (deps, l)
989
                             && !section_is_source (deps, l));
990
              if (in_literals)
991
                {
992
                  front_p = &front;
993
                  iter_stack_copy_current (stack_p, front_p);
994
                }
995
            }
996
          else
997
            {
998
              bfd_boolean is_target;
999
              current_p = ¤t;
1000
              iter_stack_copy_current (stack_p, current_p);
1001
              is_target = (section_is_target (deps, l)
1002
                           && !section_is_source (deps, l));
1003
 
1004
              if (in_literals)
1005
                {
1006
                  iter_stack_copy_current (stack_p, front_p);
1007
                  if (!is_target)
1008
                    in_literals = FALSE;
1009
                }
1010
              else
1011
                {
1012
                  if (is_target)
1013
                    {
1014
                      /* Try to insert in place.  */
1015
                      ld_xtensa_move_section_after (front_p, current_p);
1016
                      ld_assign_relative_paged_dot (0x100000,
1017
                                                    statement,
1018
                                                    deps,
1019
                                                    xtensa_use_literal_pages);
1020
 
1021
                      /* We use this code because it's already written.  */
1022
                      if (!ld_local_file_relocations_fit (statement, deps))
1023
                        {
1024
                          /* Move it back.  */
1025
                          ld_xtensa_move_section_after (current_p, front_p);
1026
                          /* Reset the literal placement.  */
1027
                          iter_stack_copy_current (stack_p, front_p);
1028
                        }
1029
                      else
1030
                        {
1031
                          /* Move front pointer up by one.  */
1032
                          front_p->loc = &(*front_p->loc)->header.next;
1033
 
1034
                          /* Do not increment the current pointer.  */
1035
                          skip_increment = TRUE;
1036
                        }
1037
                    }
1038
                }
1039
            }
1040
          break;
1041
        default:
1042
          break;
1043
        }
1044
 
1045
      if (!skip_increment)
1046
        iter_stack_next (stack_p);
1047
      else
1048
        /* Be careful to update the stack_p if it now is a null.  */
1049
        iter_stack_update (stack_p);
1050
    }
1051
 
1052
  lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement);
1053
}
1054
 
1055
 
1056
static void
1057
xtensa_move_dependencies_to_front (reloc_deps_graph *deps,
1058
                                   lang_wild_statement_type *w)
1059
{
1060
  /* Keep a front pointer and a current pointer.  */
1061
  lang_statement_union_type **front;
1062
  lang_statement_union_type **current;
1063
 
1064
  /* Walk to the end of the targets.  */
1065
  for (front = &w->children.head;
1066
       (*front != NULL) && section_is_source_or_target (deps, *front);
1067
       front = &(*front)->header.next)
1068
    ;
1069
 
1070
  if (*front == NULL)
1071
    return;
1072
 
1073
  current = &(*front)->header.next;
1074
  while (*current != NULL)
1075
    {
1076
      if (section_is_source_or_target (deps, *current))
1077
        {
1078
          /* Insert in place.  */
1079
          xtensa_ld_iter front_iter;
1080
          xtensa_ld_iter current_iter;
1081
 
1082
          front_iter.parent = (lang_statement_union_type *) w;
1083
          front_iter.l = &w->children;
1084
          front_iter.loc = front;
1085
 
1086
          current_iter.parent = (lang_statement_union_type *) w;
1087
          current_iter.l = &w->children;
1088
          current_iter.loc = current;
1089
 
1090
          ld_xtensa_move_section_after (&front_iter, ¤t_iter);
1091
          front = &(*front)->header.next;
1092
        }
1093
      else
1094
        {
1095
          current = &(*current)->header.next;
1096
        }
1097
    }
1098
}
1099
 
1100
 
1101
static bfd_boolean
1102
deps_has_sec_edge (const reloc_deps_graph *deps, asection *src, asection *tgt)
1103
{
1104
  const reloc_deps_section *sec_deps;
1105
  const reloc_deps_e *sec_deps_e;
1106
 
1107
  sec_deps = xtensa_get_section_deps (deps, src);
1108
  if (sec_deps == NULL)
1109
    return FALSE;
1110
 
1111
  for (sec_deps_e = sec_deps->succs;
1112
       sec_deps_e != NULL;
1113
       sec_deps_e = sec_deps_e->next)
1114
    {
1115
      ASSERT (sec_deps_e->src == src);
1116
      if (sec_deps_e->tgt == tgt)
1117
        return TRUE;
1118
    }
1119
  return FALSE;
1120
}
1121
 
1122
 
1123
static bfd_boolean
1124
deps_has_edge (const reloc_deps_graph *deps,
1125
               lang_statement_union_type *src,
1126
               lang_statement_union_type *tgt)
1127
{
1128
  if (!section_is_source (deps, src))
1129
    return FALSE;
1130
  if (!section_is_target (deps, tgt))
1131
    return FALSE;
1132
 
1133
  if (src->header.type != lang_input_section_enum)
1134
    return FALSE;
1135
  if (tgt->header.type != lang_input_section_enum)
1136
    return FALSE;
1137
 
1138
  return deps_has_sec_edge (deps, src->input_section.section,
1139
                            tgt->input_section.section);
1140
}
1141
 
1142
 
1143
static void
1144
add_deps_edge (reloc_deps_graph *deps, asection *src_sec, asection *tgt_sec)
1145
{
1146
  reloc_deps_section *src_sec_deps;
1147
  reloc_deps_section *tgt_sec_deps;
1148
 
1149
  reloc_deps_e *src_edge;
1150
  reloc_deps_e *tgt_edge;
1151
 
1152
  if (deps_has_sec_edge (deps, src_sec, tgt_sec))
1153
    return;
1154
 
1155
  src_sec_deps = xtensa_get_section_deps (deps, src_sec);
1156
  if (src_sec_deps == NULL)
1157
    {
1158
      /* Add a section.  */
1159
      src_sec_deps = xmalloc (sizeof (reloc_deps_section));
1160
      memset (src_sec_deps, 0, sizeof (reloc_deps_section));
1161
      src_sec_deps->is_only_literal = 0;
1162
      src_sec_deps->preds = NULL;
1163
      src_sec_deps->succs = NULL;
1164
      xtensa_set_section_deps (deps, src_sec, src_sec_deps);
1165
      xtensa_append_section_deps (deps, src_sec);
1166
    }
1167
 
1168
  tgt_sec_deps = xtensa_get_section_deps (deps, tgt_sec);
1169
  if (tgt_sec_deps == NULL)
1170
    {
1171
      /* Add a section.  */
1172
      tgt_sec_deps = xmalloc (sizeof (reloc_deps_section));
1173
      memset (tgt_sec_deps, 0, sizeof (reloc_deps_section));
1174
      tgt_sec_deps->is_only_literal = 0;
1175
      tgt_sec_deps->preds = NULL;
1176
      tgt_sec_deps->succs = NULL;
1177
      xtensa_set_section_deps (deps, tgt_sec, tgt_sec_deps);
1178
      xtensa_append_section_deps (deps, tgt_sec);
1179
    }
1180
 
1181
  /* Add the edges.  */
1182
  src_edge = xmalloc (sizeof (reloc_deps_e));
1183
  memset (src_edge, 0, sizeof (reloc_deps_e));
1184
  src_edge->src = src_sec;
1185
  src_edge->tgt = tgt_sec;
1186
  src_edge->next = src_sec_deps->succs;
1187
  src_sec_deps->succs = src_edge;
1188
 
1189
  tgt_edge = xmalloc (sizeof (reloc_deps_e));
1190
  memset (tgt_edge, 0, sizeof (reloc_deps_e));
1191
  tgt_edge->src = src_sec;
1192
  tgt_edge->tgt = tgt_sec;
1193
  tgt_edge->next = tgt_sec_deps->preds;
1194
  tgt_sec_deps->preds = tgt_edge;
1195
}
1196
 
1197
 
1198
static void
1199
build_deps_graph_callback (asection *src_sec,
1200
                           bfd_vma src_offset ATTRIBUTE_UNUSED,
1201
                           asection *target_sec,
1202
                           bfd_vma target_offset ATTRIBUTE_UNUSED,
1203
                           void *closure)
1204
{
1205
  reloc_deps_graph *deps = closure;
1206
 
1207
  /* If the target is defined.  */
1208
  if (target_sec != NULL)
1209
    add_deps_edge (deps, src_sec, target_sec);
1210
}
1211
 
1212
 
1213
static reloc_deps_graph *
1214
ld_build_required_section_dependence (lang_statement_union_type *s)
1215
{
1216
  reloc_deps_graph *deps;
1217
  xtensa_ld_iter_stack *stack = NULL;
1218
 
1219
  deps = xmalloc (sizeof (reloc_deps_graph));
1220
  deps->sections = NULL;
1221
  deps->count = 0;
1222
  deps->size = 0;
1223
 
1224
  for (iter_stack_create (&stack, s);
1225
       !iter_stack_empty (&stack);
1226
       iter_stack_next (&stack))
1227
    {
1228
      lang_statement_union_type *l = iter_stack_current (&stack);
1229
 
1230
      if (l->header.type == lang_input_section_enum)
1231
        {
1232
          lang_input_section_type *input;
1233
          input = &l->input_section;
1234
          xtensa_callback_required_dependence (input->section->owner,
1235
                                               input->section,
1236
                                               &link_info,
1237
                                               /* Use the same closure.  */
1238
                                               build_deps_graph_callback,
1239
                                               deps);
1240
        }
1241
    }
1242
  return deps;
1243
}
1244
 
1245
 
1246
#if EXTRA_VALIDATION
1247
static size_t
1248
ld_count_children (lang_statement_union_type *s)
1249
{
1250
  size_t count = 0;
1251
  xtensa_ld_iter_stack *stack = NULL;
1252
  for (iter_stack_create (&stack, s);
1253
       !iter_stack_empty (&stack);
1254
       iter_stack_next (&stack))
1255
    {
1256
      lang_statement_union_type *l = iter_stack_current (&stack);
1257
      ASSERT (l != NULL);
1258
      count++;
1259
    }
1260
  return count;
1261
}
1262
#endif /* EXTRA_VALIDATION */
1263
 
1264
 
1265
/* Check if a particular section is included in the link.  This will only
1266
   be true for one instance of a particular linkonce section.  */
1267
 
1268
static bfd_boolean input_section_found = FALSE;
1269
static asection *input_section_target = NULL;
1270
 
1271
static void
1272
input_section_linked_worker (lang_statement_union_type *statement)
1273
{
1274
  if ((statement->header.type == lang_input_section_enum
1275
       && (statement->input_section.section == input_section_target)))
1276
    input_section_found = TRUE;
1277
}
1278
 
1279
static bfd_boolean
1280
input_section_linked (asection *sec)
1281
{
1282
  input_section_found = FALSE;
1283
  input_section_target = sec;
1284
  lang_for_each_statement_worker (input_section_linked_worker, stat_ptr->head);
1285
  return input_section_found;
1286
}
1287
 
1288
 
1289
/* Strip out any linkonce property tables or XCC exception tables where the
1290
   associated linkonce text is from a different object file.  Normally,
1291
   a matching set of linkonce sections is taken from the same object file,
1292
   but sometimes the files are compiled differently so that some of the
1293
   linkonce sections are not present in all files.  Stripping the
1294
   inconsistent sections like this is not completely robust -- a much
1295
   better solution is to use comdat groups.  */
1296
 
1297
static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
1298
 
1299
static bfd_boolean
1300
is_inconsistent_linkonce_section (asection *sec)
1301
{
1302
  bfd *abfd = sec->owner;
1303
  const char *sec_name = bfd_get_section_name (abfd, sec);
1304
  const char *name;
1305
 
1306
  if ((bfd_get_section_flags (abfd, sec) & SEC_LINK_ONCE) == 0
1307
      || strncmp (sec_name, ".gnu.linkonce.", linkonce_len) != 0)
1308
    return FALSE;
1309
 
1310
  /* Check if this is an Xtensa property section or an exception table
1311
     for Tensilica's XCC compiler.  */
1312
  name = sec_name + linkonce_len;
1313
  if (CONST_STRNEQ (name, "prop."))
1314
    name = strchr (name + 5, '.') + 1;
1315
  else if (name[1] == '.'
1316
           && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h'))
1317
    name += 2;
1318
  else
1319
    name = 0;
1320
 
1321
  if (name)
1322
    {
1323
      char *dep_sec_name = xmalloc (strlen (sec_name) + 1);
1324
      asection *dep_sec;
1325
 
1326
      /* Get the associated linkonce text section and check if it is
1327
         included in the link.  If not, this section is inconsistent
1328
         and should be stripped.  */
1329
      strcpy (dep_sec_name, ".gnu.linkonce.t.");
1330
      strcat (dep_sec_name, name);
1331
      dep_sec = bfd_get_section_by_name (abfd, dep_sec_name);
1332
      if (dep_sec == NULL || ! input_section_linked (dep_sec))
1333
        {
1334
          free (dep_sec_name);
1335
          return TRUE;
1336
        }
1337
      free (dep_sec_name);
1338
    }
1339
 
1340
  return FALSE;
1341
}
1342
 
1343
 
1344
static void
1345
xtensa_strip_inconsistent_linkonce_sections (lang_statement_list_type *slist)
1346
{
1347
  lang_statement_union_type **s_p = &slist->head;
1348
  while (*s_p)
1349
    {
1350
      lang_statement_union_type *s = *s_p;
1351
      lang_statement_union_type *s_next = (*s_p)->header.next;
1352
 
1353
      switch (s->header.type)
1354
        {
1355
        case lang_input_section_enum:
1356
          if (is_inconsistent_linkonce_section (s->input_section.section))
1357
            {
1358
              s->input_section.section->output_section = bfd_abs_section_ptr;
1359
              *s_p = s_next;
1360
              continue;
1361
            }
1362
          break;
1363
 
1364
        case lang_constructors_statement_enum:
1365
          xtensa_strip_inconsistent_linkonce_sections (&constructor_list);
1366
          break;
1367
 
1368
        case lang_output_section_statement_enum:
1369
          if (s->output_section_statement.children.head)
1370
            xtensa_strip_inconsistent_linkonce_sections
1371
              (&s->output_section_statement.children);
1372
          break;
1373
 
1374
        case lang_wild_statement_enum:
1375
          xtensa_strip_inconsistent_linkonce_sections
1376
            (&s->wild_statement.children);
1377
          break;
1378
 
1379
        case lang_group_statement_enum:
1380
          xtensa_strip_inconsistent_linkonce_sections
1381
            (&s->group_statement.children);
1382
          break;
1383
 
1384
        case lang_data_statement_enum:
1385
        case lang_reloc_statement_enum:
1386
        case lang_object_symbols_statement_enum:
1387
        case lang_output_statement_enum:
1388
        case lang_target_statement_enum:
1389
        case lang_input_statement_enum:
1390
        case lang_assignment_statement_enum:
1391
        case lang_padding_statement_enum:
1392
        case lang_address_statement_enum:
1393
        case lang_fill_statement_enum:
1394
          break;
1395
 
1396
        default:
1397
          FAIL ();
1398
          break;
1399
        }
1400
 
1401
      s_p = &(*s_p)->header.next;
1402
    }
1403
 
1404
  /* Reset the tail of the list, in case the last entry was removed.  */
1405
  if (s_p != slist->tail)
1406
    slist->tail = s_p;
1407
}
1408
 
1409
 
1410
static void
1411
xtensa_wild_group_interleave_callback (lang_statement_union_type *statement)
1412
{
1413
  lang_wild_statement_type *w;
1414
  reloc_deps_graph *deps;
1415
  if (statement->header.type == lang_wild_statement_enum)
1416
    {
1417
#if EXTRA_VALIDATION
1418
      size_t old_child_count;
1419
      size_t new_child_count;
1420
#endif
1421
      bfd_boolean no_reorder;
1422
 
1423
      w = &statement->wild_statement;
1424
 
1425
      no_reorder = FALSE;
1426
 
1427
      /* If it has 0 or 1 section bound, then do not reorder.  */
1428
      if (w->children.head == NULL
1429
          || (w->children.head->header.type == lang_input_section_enum
1430
              && w->children.head->header.next == NULL))
1431
        no_reorder = TRUE;
1432
 
1433
      if (w->filenames_sorted)
1434
        no_reorder = TRUE;
1435
 
1436
      /* Check for sorting in a section list wildcard spec as well.  */
1437
      if (!no_reorder)
1438
        {
1439
          struct wildcard_list *l;
1440
          for (l = w->section_list; l != NULL; l = l->next)
1441
            {
1442
              if (l->spec.sorted == TRUE)
1443
                {
1444
                  no_reorder = TRUE;
1445
                  break;
1446
                }
1447
            }
1448
        }
1449
 
1450
      /* Special case until the NOREORDER linker directive is supported:
1451
         *(.init) output sections and *(.fini) specs may NOT be reordered.  */
1452
 
1453
      /* Check for sorting in a section list wildcard spec as well.  */
1454
      if (!no_reorder)
1455
        {
1456
          struct wildcard_list *l;
1457
          for (l = w->section_list; l != NULL; l = l->next)
1458
            {
1459
              if (l->spec.name
1460
                  && ((strcmp (".init", l->spec.name) == 0)
1461
                      || (strcmp (".fini", l->spec.name) == 0)))
1462
                {
1463
                  no_reorder = TRUE;
1464
                  break;
1465
                }
1466
            }
1467
        }
1468
 
1469
#if EXTRA_VALIDATION
1470
      old_child_count = ld_count_children (statement);
1471
#endif
1472
 
1473
      /* It is now officially a target.  Build the graph of source
1474
         section -> target section (kept as a list of edges).  */
1475
      deps = ld_build_required_section_dependence (statement);
1476
 
1477
      /* If this wildcard does not reorder....  */
1478
      if (!no_reorder && deps->count != 0)
1479
        {
1480
          /* First check for reverse dependences.  Fix if possible.  */
1481
          xtensa_layout_wild (deps, w);
1482
 
1483
          xtensa_move_dependencies_to_front (deps, w);
1484
#if EXTRA_VALIDATION
1485
          new_child_count = ld_count_children (statement);
1486
          ASSERT (new_child_count == old_child_count);
1487
#endif
1488
 
1489
          xtensa_colocate_literals (deps, statement);
1490
 
1491
#if EXTRA_VALIDATION
1492
          new_child_count = ld_count_children (statement);
1493
          ASSERT (new_child_count == old_child_count);
1494
#endif
1495
        }
1496
 
1497
      /* Clean up.  */
1498
      free_reloc_deps_graph (deps);
1499
    }
1500
}
1501
 
1502
 
1503
static void
1504
xtensa_wild_group_interleave (lang_statement_union_type *s)
1505
{
1506
  lang_for_each_statement_worker (xtensa_wild_group_interleave_callback, s);
1507
}
1508
 
1509
 
1510
static void
1511
xtensa_layout_wild (const reloc_deps_graph *deps, lang_wild_statement_type *w)
1512
{
1513
  /* If it does not fit initially, we need to do this step.  Move all
1514
     of the wild literal sections to a new list, then move each of
1515
     them back in just before the first section they depend on.  */
1516
  lang_statement_union_type **s_p;
1517
#if EXTRA_VALIDATION
1518
  size_t old_count, new_count;
1519
  size_t ct1, ct2;
1520
#endif
1521
 
1522
  lang_wild_statement_type literal_wild;
1523
  literal_wild.header.next = NULL;
1524
  literal_wild.header.type = lang_wild_statement_enum;
1525
  literal_wild.filename = NULL;
1526
  literal_wild.filenames_sorted = FALSE;
1527
  literal_wild.section_list = NULL;
1528
  literal_wild.keep_sections = FALSE;
1529
  literal_wild.children.head = NULL;
1530
  literal_wild.children.tail = &literal_wild.children.head;
1531
 
1532
#if EXTRA_VALIDATION
1533
  old_count = ld_count_children ((lang_statement_union_type*) w);
1534
#endif
1535
 
1536
  s_p = &w->children.head;
1537
  while (*s_p != NULL)
1538
    {
1539
      lang_statement_union_type *l = *s_p;
1540
      if (l->header.type == lang_input_section_enum)
1541
        {
1542
          if (section_is_target (deps, l)
1543
              && ! section_is_source (deps, l))
1544
            {
1545
              /* Detach.  */
1546
              *s_p = l->header.next;
1547
              if (*s_p == NULL)
1548
                w->children.tail = s_p;
1549
              l->header.next = NULL;
1550
 
1551
              /* Append.  */
1552
              *literal_wild.children.tail = l;
1553
              literal_wild.children.tail = &l->header.next;
1554
              continue;
1555
            }
1556
        }
1557
      s_p = &(*s_p)->header.next;
1558
    }
1559
 
1560
#if EXTRA_VALIDATION
1561
  ct1 = ld_count_children ((lang_statement_union_type*) w);
1562
  ct2 = ld_count_children ((lang_statement_union_type*) &literal_wild);
1563
 
1564
  ASSERT (old_count == (ct1 + ct2));
1565
#endif
1566
 
1567
  /* Now place them back in front of their dependent sections.  */
1568
 
1569
  while (literal_wild.children.head != NULL)
1570
    {
1571
      lang_statement_union_type *lit = literal_wild.children.head;
1572
      bfd_boolean placed = FALSE;
1573
 
1574
#if EXTRA_VALIDATION
1575
      ASSERT (ct2 > 0);
1576
      ct2--;
1577
#endif
1578
 
1579
      /* Detach.  */
1580
      literal_wild.children.head = lit->header.next;
1581
      if (literal_wild.children.head == NULL)
1582
        literal_wild.children.tail = &literal_wild.children.head;
1583
      lit->header.next = NULL;
1584
 
1585
      /* Find a spot to place it.  */
1586
      for (s_p = &w->children.head; *s_p != NULL; s_p = &(*s_p)->header.next)
1587
        {
1588
          lang_statement_union_type *src = *s_p;
1589
          if (deps_has_edge (deps, src, lit))
1590
            {
1591
              /* Place it here.  */
1592
              lit->header.next = *s_p;
1593
              *s_p = lit;
1594
              placed = TRUE;
1595
              break;
1596
            }
1597
        }
1598
 
1599
      if (!placed)
1600
        {
1601
          /* Put it at the end.  */
1602
          *w->children.tail = lit;
1603
          w->children.tail = &lit->header.next;
1604
        }
1605
    }
1606
 
1607
#if EXTRA_VALIDATION
1608
  new_count = ld_count_children ((lang_statement_union_type*) w);
1609
  ASSERT (new_count == old_count);
1610
#endif
1611
}
1612
 
1613
 
1614
static void
1615
xtensa_colocate_output_literals_callback (lang_statement_union_type *statement)
1616
{
1617
  reloc_deps_graph *deps;
1618
  if (statement->header.type == lang_output_section_statement_enum)
1619
    {
1620
      /* Now, we walk over the contours of the output section statement.
1621
 
1622
         First we build the literal section dependences as before.
1623
 
1624
         At the first uniquely_literal section, we mark it as a good
1625
         spot to place other literals.  Continue walking (and counting
1626
         sizes) until we find the next literal section.  If this
1627
         section can be moved to the first one, then we move it.  If
1628
         we every find a modification of ".", start over.  If we find
1629
         a labeling of the current location, start over.  Finally, at
1630
         the end, if we require page alignment, add page alignments.  */
1631
 
1632
#if EXTRA_VALIDATION
1633
      size_t old_child_count;
1634
      size_t new_child_count;
1635
#endif
1636
      bfd_boolean no_reorder = FALSE;
1637
 
1638
#if EXTRA_VALIDATION
1639
      old_child_count = ld_count_children (statement);
1640
#endif
1641
 
1642
      /* It is now officially a target.  Build the graph of source
1643
         section -> target section (kept as a list of edges).  */
1644
 
1645
      deps = ld_build_required_section_dependence (statement);
1646
 
1647
      /* If this wildcard does not reorder....  */
1648
      if (!no_reorder)
1649
        {
1650
          /* First check for reverse dependences.  Fix if possible.  */
1651
          xtensa_colocate_literals (deps, statement);
1652
 
1653
#if EXTRA_VALIDATION
1654
          new_child_count = ld_count_children (statement);
1655
          ASSERT (new_child_count == old_child_count);
1656
#endif
1657
        }
1658
 
1659
      /* Insert align/offset assignment statement.  */
1660
      if (xtensa_use_literal_pages)
1661
        {
1662
          ld_xtensa_insert_page_offsets (0, statement, deps,
1663
                                         xtensa_use_literal_pages);
1664
          lang_for_each_statement_worker (xtensa_ldlang_clear_addresses,
1665
                                          statement);
1666
        }
1667
 
1668
      /* Clean up.  */
1669
      free_reloc_deps_graph (deps);
1670
    }
1671
}
1672
 
1673
 
1674
static void
1675
xtensa_colocate_output_literals (lang_statement_union_type *s)
1676
{
1677
  lang_for_each_statement_worker (xtensa_colocate_output_literals_callback, s);
1678
}
1679
 
1680
 
1681
static void
1682
xtensa_ldlang_clear_addresses (lang_statement_union_type *statement)
1683
{
1684
  switch (statement->header.type)
1685
    {
1686
    case lang_input_section_enum:
1687
      {
1688
        asection *bfd_section = statement->input_section.section;
1689
        bfd_section->output_offset = 0;
1690
      }
1691
      break;
1692
    default:
1693
      break;
1694
    }
1695
}
1696
 
1697
 
1698
static bfd_vma
1699
ld_assign_relative_paged_dot (bfd_vma dot,
1700
                              lang_statement_union_type *s,
1701
                              const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
1702
                              bfd_boolean lit_align)
1703
{
1704
  /* Walk through all of the input statements in this wild statement
1705
     assign dot to all of them.  */
1706
 
1707
  xtensa_ld_iter_stack *stack = NULL;
1708
  xtensa_ld_iter_stack **stack_p = &stack;
1709
 
1710
  bfd_boolean first_section = FALSE;
1711
  bfd_boolean in_literals = FALSE;
1712
 
1713
  for (iter_stack_create (stack_p, s);
1714
       !iter_stack_empty (stack_p);
1715
       iter_stack_next (stack_p))
1716
    {
1717
      lang_statement_union_type *l = iter_stack_current (stack_p);
1718
 
1719
      switch (l->header.type)
1720
        {
1721
        case lang_input_section_enum:
1722
          {
1723
            asection *section = l->input_section.section;
1724
            size_t align_pow = section->alignment_power;
1725
            bfd_boolean do_xtensa_alignment = FALSE;
1726
 
1727
            if (lit_align)
1728
              {
1729
                bfd_boolean sec_is_target = section_is_target (deps, l);
1730
                bfd_boolean sec_is_source = section_is_source (deps, l);
1731
 
1732
                if (section->size != 0
1733
                    && (first_section
1734
                        || (in_literals && !sec_is_target)
1735
                        || (!in_literals && sec_is_target)))
1736
                  {
1737
                    do_xtensa_alignment = TRUE;
1738
                  }
1739
                first_section = FALSE;
1740
                if (section->size != 0)
1741
                  in_literals = (sec_is_target && !sec_is_source);
1742
              }
1743
 
1744
            if (do_xtensa_alignment && xtensa_page_power != 0)
1745
              dot += (1 << xtensa_page_power);
1746
 
1747
            dot = align_power (dot, align_pow);
1748
            section->output_offset = dot;
1749
            dot += section->size;
1750
          }
1751
          break;
1752
        case lang_fill_statement_enum:
1753
          dot += l->fill_statement.size;
1754
          break;
1755
        case lang_padding_statement_enum:
1756
          dot += l->padding_statement.size;
1757
          break;
1758
        default:
1759
          break;
1760
        }
1761
    }
1762
  return dot;
1763
}
1764
 
1765
 
1766
static bfd_boolean
1767
ld_local_file_relocations_fit (lang_statement_union_type *statement,
1768
                               const reloc_deps_graph *deps ATTRIBUTE_UNUSED)
1769
{
1770
  /* Walk over all of the dependencies that we identified and make
1771
     sure that IF the source and target are here (addr != 0):
1772
     1) target addr < source addr
1773
     2) (roundup(source + source_size, 4) - rounddown(target, 4))
1774
        < (256K - (1 << bad align))
1775
     Need a worst-case proof....  */
1776
 
1777
  xtensa_ld_iter_stack *stack = NULL;
1778
  xtensa_ld_iter_stack **stack_p = &stack;
1779
  size_t max_align_power = 0;
1780
  size_t align_penalty = 256;
1781
  reloc_deps_e *e;
1782
  size_t i;
1783
 
1784
  /* Find the worst-case alignment requirement for this set of statements.  */
1785
  for (iter_stack_create (stack_p, statement);
1786
       !iter_stack_empty (stack_p);
1787
       iter_stack_next (stack_p))
1788
    {
1789
      lang_statement_union_type *l = iter_stack_current (stack_p);
1790
      if (l->header.type == lang_input_section_enum)
1791
        {
1792
          lang_input_section_type *input = &l->input_section;
1793
          asection *section = input->section;
1794
          if (section->alignment_power > max_align_power)
1795
            max_align_power = section->alignment_power;
1796
        }
1797
    }
1798
 
1799
  /* Now check that everything fits.  */
1800
  for (i = 0; i < deps->count; i++)
1801
    {
1802
      asection *sec = deps->sections[i];
1803
      const reloc_deps_section *deps_section =
1804
        xtensa_get_section_deps (deps, sec);
1805
      if (deps_section)
1806
        {
1807
          /* We choose to walk through the successors.  */
1808
          for (e = deps_section->succs; e != NULL; e = e->next)
1809
            {
1810
              if (e->src != e->tgt
1811
                  && e->src->output_section == e->tgt->output_section
1812
                  && e->src->output_offset != 0
1813
                  && e->tgt->output_offset != 0)
1814
                {
1815
                  bfd_vma l32r_addr =
1816
                    align_power (e->src->output_offset + e->src->size, 2);
1817
                  bfd_vma target_addr = e->tgt->output_offset & ~3;
1818
                  if (l32r_addr < target_addr)
1819
                    {
1820
                      fflush (stdout);
1821
                      fprintf (stderr, "Warning: "
1822
                               "l32r target section before l32r\n");
1823
                      fflush (stderr);
1824
                      return FALSE;
1825
                    }
1826
 
1827
                  if (l32r_addr - target_addr > 256 * 1024 - align_penalty)
1828
                    return FALSE;
1829
                }
1830
            }
1831
        }
1832
    }
1833
 
1834
  return TRUE;
1835
}
1836
 
1837
 
1838
static bfd_vma
1839
ld_xtensa_insert_page_offsets (bfd_vma dot,
1840
                               lang_statement_union_type *s,
1841
                               reloc_deps_graph *deps,
1842
                               bfd_boolean lit_align)
1843
{
1844
  xtensa_ld_iter_stack *stack = NULL;
1845
  xtensa_ld_iter_stack **stack_p = &stack;
1846
 
1847
  bfd_boolean first_section = FALSE;
1848
  bfd_boolean in_literals = FALSE;
1849
 
1850
  if (!lit_align)
1851
    return FALSE;
1852
 
1853
  for (iter_stack_create (stack_p, s);
1854
       !iter_stack_empty (stack_p);
1855
       iter_stack_next (stack_p))
1856
    {
1857
      lang_statement_union_type *l = iter_stack_current (stack_p);
1858
 
1859
      switch (l->header.type)
1860
        {
1861
        case lang_input_section_enum:
1862
          {
1863
            asection *section = l->input_section.section;
1864
            bfd_boolean do_xtensa_alignment = FALSE;
1865
 
1866
            if (lit_align)
1867
              {
1868
                if (section->size != 0
1869
                    && (first_section
1870
                        || (in_literals && !section_is_target (deps, l))
1871
                        || (!in_literals && section_is_target (deps, l))))
1872
                  {
1873
                    do_xtensa_alignment = TRUE;
1874
                  }
1875
                first_section = FALSE;
1876
                if (section->size != 0)
1877
                  {
1878
                    in_literals = (section_is_target (deps, l)
1879
                                   && !section_is_source (deps, l));
1880
                  }
1881
              }
1882
 
1883
            if (do_xtensa_alignment && xtensa_page_power != 0)
1884
              {
1885
                /* Create an expression that increments the current address,
1886
                   i.e., "dot", by (1 << xtensa_align_power).  */
1887
                etree_type *name_op = exp_nameop (NAME, ".");
1888
                etree_type *addend_op = exp_intop (1 << xtensa_page_power);
1889
                etree_type *add_op = exp_binop ('+', name_op, addend_op);
1890
                etree_type *assign_op = exp_assign (".", add_op);
1891
 
1892
                lang_assignment_statement_type *assign_stmt;
1893
                lang_statement_union_type *assign_union;
1894
                lang_statement_list_type tmplist;
1895
 
1896
                /* There is hidden state in "lang_add_assignment".  It
1897
                   appends the new assignment statement to the stat_ptr
1898
                   list.  Thus, we swap it before and after the call.  */
1899
 
1900
                lang_list_init (&tmplist);
1901
                push_stat_ptr (&tmplist);
1902
                /* Warning: side effect; statement appended to stat_ptr.  */
1903
                assign_stmt = lang_add_assignment (assign_op);
1904
                assign_union = (lang_statement_union_type *) assign_stmt;
1905
                pop_stat_ptr ();
1906
 
1907
                assign_union->header.next = l;
1908
                *(*stack_p)->iterloc.loc = assign_union;
1909
                iter_stack_next (stack_p);
1910
              }
1911
          }
1912
          break;
1913
        default:
1914
          break;
1915
        }
1916
    }
1917
  return dot;
1918
}
1919
 
1920
EOF
1921
 
1922
# Define some shell vars to insert bits of code into the standard ELF
1923
# parse_args and list_options functions.
1924
#
1925
PARSE_AND_LIST_PROLOGUE='
1926
#define OPTION_OPT_SIZEOPT              (300)
1927
#define OPTION_LITERAL_MOVEMENT         (OPTION_OPT_SIZEOPT + 1)
1928
#define OPTION_NO_LITERAL_MOVEMENT      (OPTION_LITERAL_MOVEMENT + 1)
1929
extern int elf32xtensa_size_opt;
1930
extern int elf32xtensa_no_literal_movement;
1931
'
1932
 
1933
PARSE_AND_LIST_LONGOPTS='
1934
  { "size-opt", no_argument, NULL, OPTION_OPT_SIZEOPT},
1935
  { "literal-movement", no_argument, NULL, OPTION_LITERAL_MOVEMENT},
1936
  { "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
1937
'
1938
 
1939
PARSE_AND_LIST_OPTIONS='
1940
  fprintf (file, _("\
1941
  --size-opt                  When relaxing longcalls, prefer size\n\
1942
                                optimization over branch target alignment\n"));
1943
'
1944
 
1945
PARSE_AND_LIST_ARGS_CASES='
1946
    case OPTION_OPT_SIZEOPT:
1947
      elf32xtensa_size_opt = 1;
1948
      break;
1949
    case OPTION_LITERAL_MOVEMENT:
1950
      elf32xtensa_no_literal_movement = 0;
1951
      break;
1952
    case OPTION_NO_LITERAL_MOVEMENT:
1953
      elf32xtensa_no_literal_movement = 1;
1954
      break;
1955
'
1956
 
1957
# Replace some of the standard ELF functions with our own versions.
1958
#
1959
LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse
1960
LDEMUL_AFTER_OPEN=elf_xtensa_after_open
1961
LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target
1962
LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.