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

Subversion Repositories open8_urisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 khays
# This shell script emits a C file. -*- C -*-
2 166 khays
# Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 145 khays
# 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 powerpc64-elf
24
# specific routines.
25
#
26
fragment <
27
 
28
#include "ldctor.h"
29
#include "libbfd.h"
30
#include "elf-bfd.h"
31
#include "elf64-ppc.h"
32
 
33
/* Fake input file for stubs.  */
34
static lang_input_statement_type *stub_file;
35
static int stub_added = 0;
36
 
37
/* Whether we need to call ppc_layout_sections_again.  */
38
static int need_laying_out = 0;
39
 
40
/* Maximum size of a group of input sections that can be handled by
41
   one stub section.  A value of +/-1 indicates the bfd back-end
42
   should use a suitable default size.  */
43
static bfd_signed_vma group_size = 1;
44
 
45
/* Whether to add ".foo" entries for each "foo" in a version script.  */
46
static int dotsyms = 1;
47
 
48
/* Whether to run tls optimization.  */
49
static int no_tls_opt = 0;
50
static int no_tls_get_addr_opt = 0;
51
 
52
/* Whether to run opd optimization.  */
53
static int no_opd_opt = 0;
54
 
55
/* Whether to run toc optimization.  */
56
static int no_toc_opt = 0;
57
 
58
/* Whether to allow multiple toc sections.  */
59
static int no_multi_toc = 0;
60
 
61
/* Whether to sort input toc and got sections.  */
62
static int no_toc_sort = 0;
63
 
64 157 khays
/* Set if PLT call stubs should load r11.  */
65 166 khays
static int plt_static_chain = ${DEFAULT_PLT_STATIC_CHAIN-0};
66 157 khays
 
67 166 khays
/* Set if PLT call stubs need to be thread safe on power7+.  */
68
static int plt_thread_safe = -1;
69
 
70
/* Set if individual PLT call stubs should be aligned.  */
71
static int plt_stub_align = 0;
72
 
73 145 khays
/* Whether to emit symbols for stubs.  */
74
static int emit_stub_syms = -1;
75
 
76
static asection *toc_section = 0;
77
 
78
/* Whether to canonicalize .opd so that there are no overlapping
79
   .opd entries.  */
80
static int non_overlapping_opd = 0;
81
 
82
/* This is called before the input files are opened.  We create a new
83
   fake input file to hold the stub sections.  */
84
 
85
static void
86
ppc_create_output_section_statements (void)
87
{
88
  if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
89
        && elf_object_id (link_info.output_bfd) == PPC64_ELF_DATA))
90
    return;
91
 
92
  link_info.wrap_char = '.';
93
 
94
  stub_file = lang_add_input_file ("linker stubs",
95
                                   lang_input_file_is_fake_enum,
96
                                   NULL);
97
  stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
98
  if (stub_file->the_bfd == NULL
99
      || !bfd_set_arch_mach (stub_file->the_bfd,
100
                             bfd_get_arch (link_info.output_bfd),
101
                             bfd_get_mach (link_info.output_bfd)))
102
    {
103 163 khays
      einfo ("%F%P: can not create BFD: %E\n");
104 145 khays
      return;
105
    }
106
 
107
  stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
108
  ldlang_add_file (stub_file);
109
  ppc64_elf_init_stub_bfd (stub_file->the_bfd, &link_info);
110
}
111
 
112
/* Move the input section statement at *U which happens to be on LIST
113
   to be just before *TO.  */
114
 
115
static void
116
move_input_section (lang_statement_list_type *list,
117
                    lang_statement_union_type **u,
118
                    lang_statement_union_type **to)
119
{
120
  lang_statement_union_type *s = *u;
121
  asection *i = s->input_section.section;
122
  asection *p, *n;
123
 
124
  /* Snip the input section from the statement list.  If it was the
125
     last statement, fix the list tail pointer.  */
126
  *u = s->header.next;
127
  if (*u == NULL)
128
    list->tail = u;
129
  /* Add it back in the new position.  */
130
  s->header.next = *to;
131
  *to = s;
132
  if (list->tail == to)
133
    list->tail = &s->header.next;
134
 
135
  /* Trim I off the bfd map_head/map_tail doubly linked lists.  */
136
  n = i->map_head.s;
137
  p = i->map_tail.s;
138
  (p != NULL ? p : i->output_section)->map_head.s = n;
139
  (n != NULL ? n : i->output_section)->map_tail.s = p;
140
 
141
  /* Add I back on in its new position.  */
142
  if (s->header.next->header.type == lang_input_section_enum)
143
    {
144
      n = s->header.next->input_section.section;
145
      p = n->map_tail.s;
146
    }
147
  else
148
    {
149
      /* If the next statement is not an input section statement then
150
         TO must point at the previous input section statement
151
         header.next field.  */
152
      lang_input_section_type *prev = (lang_input_section_type *)
153
        ((char *) to - offsetof (lang_statement_union_type, header.next));
154
 
155
      ASSERT (prev->header.type == lang_input_section_enum);
156
      p = prev->section;
157
      n = p->map_head.s;
158
    }
159
  i->map_head.s = n;
160
  i->map_tail.s = p;
161
  (p != NULL ? p : i->output_section)->map_head.s = i;
162
  (n != NULL ? n : i->output_section)->map_tail.s = i;
163
}
164
 
165
/* Sort input section statements in the linker script tree rooted at
166
   LIST so that those whose owning bfd happens to have a section
167
   called .init or .fini are placed first.  Place any TOC sections
168
   referenced by small TOC relocs next, with TOC sections referenced
169
   only by bigtoc relocs last.  */
170
 
171
static void
172
sort_toc_sections (lang_statement_list_type *list,
173
                   lang_statement_union_type **ini,
174
                   lang_statement_union_type **small)
175
{
176
  lang_statement_union_type *s, **u;
177
  asection *i;
178
 
179
  u = &list->head;
180
  while ((s = *u) != NULL)
181
    {
182
      switch (s->header.type)
183
        {
184
        case lang_wild_statement_enum:
185
          sort_toc_sections (&s->wild_statement.children, ini, small);
186
          break;
187
 
188
        case lang_group_statement_enum:
189
          sort_toc_sections (&s->group_statement.children, ini, small);
190
          break;
191
 
192
        case lang_input_section_enum:
193
          i = s->input_section.section;
194
          /* Leave the stub_file .got where it is.  We put the .got
195
             header there.  */
196
          if (i->owner == stub_file->the_bfd)
197
            break;
198
          if (bfd_get_section_by_name (i->owner, ".init") != NULL
199
              || bfd_get_section_by_name (i->owner, ".fini") != NULL)
200
            {
201
              if (ini != NULL && *ini != s)
202
                {
203
                  move_input_section (list, u, ini);
204
                  if (small == ini)
205
                    small = &s->header.next;
206
                  ini = &s->header.next;
207
                  continue;
208
                }
209
              if (small == ini)
210
                small = &s->header.next;
211
              ini = &s->header.next;
212
              break;
213
            }
214
          else if (ini == NULL)
215
            ini = u;
216
 
217
          if (ppc64_elf_has_small_toc_reloc (i))
218
            {
219
              if (small != NULL && *small != s)
220
                {
221
                  move_input_section (list, u, small);
222
                  small = &s->header.next;
223
                  continue;
224
                }
225
              small = &s->header.next;
226
            }
227
          else if (small == NULL)
228
            small = u;
229
          break;
230
 
231
        default:
232
          break;
233
        }
234
      u = &s->header.next;
235
    }
236
}
237
 
238
static void
239
prelim_size_sections (void)
240
{
241
  if (expld.phase != lang_mark_phase_enum)
242
    {
243
      expld.phase = lang_mark_phase_enum;
244
      expld.dataseg.phase = exp_dataseg_none;
245
      one_lang_size_sections_pass (NULL, FALSE);
246
      /* We must not cache anything from the preliminary sizing.  */
247
      lang_reset_memory_regions ();
248
    }
249
}
250
 
251
static void
252
ppc_before_allocation (void)
253
{
254
  if (stub_file != NULL)
255
    {
256
      if (!no_opd_opt
257
          && !ppc64_elf_edit_opd (&link_info, non_overlapping_opd))
258 163 khays
        einfo ("%X%P: can not edit %s: %E\n", "opd");
259 145 khays
 
260
      if (ppc64_elf_tls_setup (&link_info, no_tls_get_addr_opt, &no_multi_toc)
261
          && !no_tls_opt)
262
        {
263
          /* Size the sections.  This is premature, but we want to know the
264
             TLS segment layout so that certain optimizations can be done.  */
265
          prelim_size_sections ();
266
 
267
          if (!ppc64_elf_tls_optimize (&link_info))
268
            einfo ("%X%P: TLS problem %E\n");
269
        }
270
 
271
      if (!no_toc_opt
272
          && !link_info.relocatable)
273
        {
274
          prelim_size_sections ();
275
 
276
          if (!ppc64_elf_edit_toc (&link_info))
277 163 khays
            einfo ("%X%P: can not edit %s: %E\n", "toc");
278 145 khays
        }
279
 
280
      if (!no_toc_sort)
281
        {
282
          lang_output_section_statement_type *toc_os;
283
 
284
          toc_os = lang_output_section_find (".got");
285
          if (toc_os != NULL)
286
            sort_toc_sections (&toc_os->children, NULL, NULL);
287
        }
288
    }
289
 
290
  gld${EMULATION_NAME}_before_allocation ();
291
}
292
 
293
struct hook_stub_info
294
{
295
  lang_statement_list_type add;
296
  asection *input_section;
297
};
298
 
299
/* Traverse the linker tree to find the spot where the stub goes.  */
300
 
301
static bfd_boolean
302
hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
303
{
304
  lang_statement_union_type *l;
305
  bfd_boolean ret;
306
 
307
  for (; (l = *lp) != NULL; lp = &l->header.next)
308
    {
309
      switch (l->header.type)
310
        {
311
        case lang_constructors_statement_enum:
312
          ret = hook_in_stub (info, &constructor_list.head);
313
          if (ret)
314
            return ret;
315
          break;
316
 
317
        case lang_output_section_statement_enum:
318
          ret = hook_in_stub (info,
319
                              &l->output_section_statement.children.head);
320
          if (ret)
321
            return ret;
322
          break;
323
 
324
        case lang_wild_statement_enum:
325
          ret = hook_in_stub (info, &l->wild_statement.children.head);
326
          if (ret)
327
            return ret;
328
          break;
329
 
330
        case lang_group_statement_enum:
331
          ret = hook_in_stub (info, &l->group_statement.children.head);
332
          if (ret)
333
            return ret;
334
          break;
335
 
336
        case lang_input_section_enum:
337
          if (l->input_section.section == info->input_section)
338
            {
339
              /* We've found our section.  Insert the stub immediately
340
                 before its associated input section.  */
341
              *lp = info->add.head;
342
              *(info->add.tail) = l;
343
              return TRUE;
344
            }
345
          break;
346
 
347
        case lang_data_statement_enum:
348
        case lang_reloc_statement_enum:
349
        case lang_object_symbols_statement_enum:
350
        case lang_output_statement_enum:
351
        case lang_target_statement_enum:
352
        case lang_input_statement_enum:
353
        case lang_assignment_statement_enum:
354
        case lang_padding_statement_enum:
355
        case lang_address_statement_enum:
356
        case lang_fill_statement_enum:
357
          break;
358
 
359
        default:
360
          FAIL ();
361
          break;
362
        }
363
    }
364
  return FALSE;
365
}
366
 
367
 
368
/* Call-back for ppc64_elf_size_stubs.  */
369
 
370
/* Create a new stub section, and arrange for it to be linked
371
   immediately before INPUT_SECTION.  */
372
 
373
static asection *
374
ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
375
{
376
  asection *stub_sec;
377
  flagword flags;
378
  asection *output_section;
379
  const char *secname;
380
  lang_output_section_statement_type *os;
381
  struct hook_stub_info info;
382
 
383
  flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
384
           | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
385
  stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
386
                                                 stub_sec_name, flags);
387 163 khays
  if (stub_sec == NULL
388 166 khays
      || !bfd_set_section_alignment (stub_file->the_bfd, stub_sec,
389
                                     plt_stub_align > 5 ? plt_stub_align : 5))
390 145 khays
    goto err_ret;
391
 
392
  output_section = input_section->output_section;
393
  secname = bfd_get_section_name (output_section->owner, output_section);
394
  os = lang_output_section_find (secname);
395
 
396
  info.input_section = input_section;
397
  lang_list_init (&info.add);
398
  lang_add_section (&info.add, stub_sec, os);
399
 
400
  if (info.add.head == NULL)
401
    goto err_ret;
402
 
403
  stub_added = 1;
404
  if (hook_in_stub (&info, &os->children.head))
405
    return stub_sec;
406
 
407
 err_ret:
408
  einfo ("%X%P: can not make stub section: %E\n");
409
  return NULL;
410
}
411
 
412
 
413
/* Another call-back for ppc64_elf_size_stubs.  */
414
 
415
static void
416
ppc_layout_sections_again (void)
417
{
418
  /* If we have changed sizes of the stub sections, then we need
419
     to recalculate all the section offsets.  This may mean we need to
420
     add even more stubs.  */
421
  gld${EMULATION_NAME}_map_segments (TRUE);
422
 
423
  if (!link_info.relocatable)
424
    _bfd_set_gp_value (link_info.output_bfd,
425
                       ppc64_elf_toc (link_info.output_bfd));
426
 
427
  need_laying_out = -1;
428
}
429
 
430
 
431
static void
432
build_toc_list (lang_statement_union_type *statement)
433
{
434
  if (statement->header.type == lang_input_section_enum)
435
    {
436
      asection *i = statement->input_section.section;
437
 
438
      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
439
          && (i->flags & SEC_EXCLUDE) == 0
440
          && i->output_section == toc_section)
441
        {
442
          if (!ppc64_elf_next_toc_section (&link_info, i))
443
            einfo ("%X%P: linker script separates .got and .toc\n");
444
        }
445
    }
446
}
447
 
448
 
449
static void
450
build_section_lists (lang_statement_union_type *statement)
451
{
452
  if (statement->header.type == lang_input_section_enum)
453
    {
454
      asection *i = statement->input_section.section;
455
 
456
      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
457
          && (i->flags & SEC_EXCLUDE) == 0
458
          && i->output_section != NULL
459
          && i->output_section->owner == link_info.output_bfd)
460
        {
461
          if (!ppc64_elf_next_input_section (&link_info, i))
462
            einfo ("%X%P: can not size stub section: %E\n");
463
        }
464
    }
465
}
466
 
467
 
468
/* Call the back-end function to set TOC base after we have placed all
469
   the sections.  */
470
static void
471
gld${EMULATION_NAME}_after_allocation (void)
472
{
473
  /* bfd_elf_discard_info just plays with data and debugging sections,
474
     ie. doesn't affect code size, so we can delay resizing the
475
     sections.  It's likely we'll resize everything in the process of
476
     adding stubs.  */
477
  if (bfd_elf_discard_info (link_info.output_bfd, &link_info))
478
    need_laying_out = 1;
479
 
480
  /* If generating a relocatable output file, then we don't have any
481
     stubs.  */
482
  if (stub_file != NULL && !link_info.relocatable)
483
    {
484
      int ret = ppc64_elf_setup_section_lists (&link_info,
485
                                               &ppc_add_stub_section,
486
                                               &ppc_layout_sections_again);
487
      if (ret < 0)
488
        einfo ("%X%P: can not size stub section: %E\n");
489
      else if (ret > 0)
490
        {
491
          ppc64_elf_start_multitoc_partition (&link_info);
492
 
493
          if (!no_multi_toc)
494
            {
495
              toc_section = bfd_get_section_by_name (link_info.output_bfd,
496
                                                     ".got");
497
              if (toc_section != NULL)
498
                lang_for_each_statement (build_toc_list);
499
            }
500
 
501
          if (ppc64_elf_layout_multitoc (&link_info)
502
              && !no_multi_toc
503
              && toc_section != NULL)
504
            lang_for_each_statement (build_toc_list);
505
 
506
          ppc64_elf_finish_multitoc_partition (&link_info);
507
 
508
          lang_for_each_statement (build_section_lists);
509
 
510
          if (!ppc64_elf_check_init_fini (&link_info))
511
            einfo ("%P: .init/.fini fragments use differing TOC pointers\n");
512
 
513
          /* Call into the BFD backend to do the real work.  */
514 166 khays
          if (!ppc64_elf_size_stubs (&link_info, group_size,
515
                                     plt_static_chain, plt_thread_safe,
516
                                     plt_stub_align))
517 145 khays
            einfo ("%X%P: can not size stub section: %E\n");
518
        }
519
    }
520
 
521
  if (need_laying_out != -1)
522
    {
523
      gld${EMULATION_NAME}_map_segments (need_laying_out);
524
 
525
      if (!link_info.relocatable)
526
        _bfd_set_gp_value (link_info.output_bfd,
527
                           ppc64_elf_toc (link_info.output_bfd));
528
    }
529
}
530
 
531
 
532
/* Final emulation specific call.  */
533
 
534
static void
535
gld${EMULATION_NAME}_finish (void)
536
{
537
  /* e_entry on PowerPC64 points to the function descriptor for
538
     _start.  If _start is missing, default to the first function
539
     descriptor in the .opd section.  */
540
  entry_section = ".opd";
541
 
542
  if (stub_added)
543
    {
544
      char *msg = NULL;
545
      char *line, *endline;
546
 
547
      if (emit_stub_syms < 0)
548
        emit_stub_syms = 1;
549
      if (!ppc64_elf_build_stubs (emit_stub_syms, &link_info,
550
                                  config.stats ? &msg : NULL))
551
        einfo ("%X%P: can not build stubs: %E\n");
552
 
553
      fflush (stdout);
554
      for (line = msg; line != NULL; line = endline)
555
        {
556
          endline = strchr (line, '\n');
557
          if (endline != NULL)
558
            *endline++ = '\0';
559
          fprintf (stderr, "%s: %s\n", program_name, line);
560
        }
561
      fflush (stderr);
562
      if (msg != NULL)
563
        free (msg);
564
    }
565
 
566
  ppc64_elf_restore_symbols (&link_info);
567
  finish_default ();
568
}
569
 
570
 
571
/* Add a pattern matching ".foo" for every "foo" in a version script.
572
 
573
   The reason for doing this is that many shared library version
574
   scripts export a selected set of functions or data symbols, forcing
575
   others local.  eg.
576
 
577
   . VERS_1 {
578
   .       global:
579
   .               this; that; some; thing;
580
   .       local:
581
   .               *;
582
   .   };
583
 
584
   To make the above work for PowerPC64, we need to export ".this",
585
   ".that" and so on, otherwise only the function descriptor syms are
586
   exported.  Lack of an exported function code sym may cause a
587
   definition to be pulled in from a static library.  */
588
 
589
static struct bfd_elf_version_expr *
590
gld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
591
{
592
  struct bfd_elf_version_expr *dot_entry;
593
  unsigned int len;
594
  char *dot_pat;
595
 
596
  if (!dotsyms
597
      || entry->pattern[0] == '.'
598
      || (!entry->literal && entry->pattern[0] == '*'))
599
    return entry;
600
 
601
  dot_entry = xmalloc (sizeof *dot_entry);
602
  *dot_entry = *entry;
603
  dot_entry->next = entry;
604
  len = strlen (entry->pattern) + 2;
605
  dot_pat = xmalloc (len);
606
  dot_pat[0] = '.';
607
  memcpy (dot_pat + 1, entry->pattern, len - 1);
608
  dot_entry->pattern = dot_pat;
609
  dot_entry->script = 1;
610
  return dot_entry;
611
}
612
 
613
 
614
/* Avoid processing the fake stub_file in vercheck, stat_needed and
615
   check_needed routines.  */
616
 
617
static void (*real_func) (lang_input_statement_type *);
618
 
619
static void ppc_for_each_input_file_wrapper (lang_input_statement_type *l)
620
{
621
  if (l != stub_file)
622
    (*real_func) (l);
623
}
624
 
625
static void
626
ppc_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
627
{
628
  real_func = func;
629
  lang_for_each_input_file (&ppc_for_each_input_file_wrapper);
630
}
631
 
632
#define lang_for_each_input_file ppc_lang_for_each_input_file
633
 
634
EOF
635
 
636
if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
637
  fragment <
638
/* Special handling for embedded SPU executables.  */
639
extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
640
static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *);
641
 
642
static bfd_boolean
643
ppc64_recognized_file (lang_input_statement_type *entry)
644
{
645
  if (embedded_spu_file (entry, "-m64"))
646
    return TRUE;
647
 
648
  return gld${EMULATION_NAME}_load_symbols (entry);
649
}
650
EOF
651
LDEMUL_RECOGNIZED_FILE=ppc64_recognized_file
652
fi
653
 
654
# Define some shell vars to insert bits of code into the standard elf
655
# parse_args and list_options functions.
656
#
657 157 khays
PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
658
#define OPTION_STUBGROUP_SIZE           321
659
#define OPTION_PLT_STATIC_CHAIN         (OPTION_STUBGROUP_SIZE + 1)
660
#define OPTION_NO_PLT_STATIC_CHAIN      (OPTION_PLT_STATIC_CHAIN + 1)
661 166 khays
#define OPTION_PLT_THREAD_SAFE          (OPTION_NO_PLT_STATIC_CHAIN + 1)
662
#define OPTION_NO_PLT_THREAD_SAFE       (OPTION_PLT_THREAD_SAFE + 1)
663
#define OPTION_PLT_ALIGN                (OPTION_NO_PLT_THREAD_SAFE + 1)
664
#define OPTION_NO_PLT_ALIGN             (OPTION_PLT_ALIGN + 1)
665
#define OPTION_STUBSYMS                 (OPTION_NO_PLT_ALIGN + 1)
666 145 khays
#define OPTION_NO_STUBSYMS              (OPTION_STUBSYMS + 1)
667
#define OPTION_DOTSYMS                  (OPTION_NO_STUBSYMS + 1)
668
#define OPTION_NO_DOTSYMS               (OPTION_DOTSYMS + 1)
669
#define OPTION_NO_TLS_OPT               (OPTION_NO_DOTSYMS + 1)
670
#define OPTION_NO_TLS_GET_ADDR_OPT      (OPTION_NO_TLS_OPT + 1)
671
#define OPTION_NO_OPD_OPT               (OPTION_NO_TLS_GET_ADDR_OPT + 1)
672
#define OPTION_NO_TOC_OPT               (OPTION_NO_OPD_OPT + 1)
673
#define OPTION_NO_MULTI_TOC             (OPTION_NO_TOC_OPT + 1)
674
#define OPTION_NO_TOC_SORT              (OPTION_NO_MULTI_TOC + 1)
675
#define OPTION_NON_OVERLAPPING_OPD      (OPTION_NO_TOC_SORT + 1)
676
'
677
 
678 157 khays
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
679 145 khays
  { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
680 157 khays
  { "plt-static-chain", no_argument, NULL, OPTION_PLT_STATIC_CHAIN },
681
  { "no-plt-static-chain", no_argument, NULL, OPTION_NO_PLT_STATIC_CHAIN },
682 166 khays
  { "plt-thread-safe", no_argument, NULL, OPTION_PLT_THREAD_SAFE },
683
  { "no-plt-thread-safe", no_argument, NULL, OPTION_NO_PLT_THREAD_SAFE },
684
  { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
685
  { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
686 145 khays
  { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
687
  { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
688
  { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
689
  { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
690
  { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
691
  { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
692
  { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
693
  { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
694
  { "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
695
  { "no-toc-sort", no_argument, NULL, OPTION_NO_TOC_SORT },
696
  { "non-overlapping-opd", no_argument, NULL, OPTION_NON_OVERLAPPING_OPD },
697
'
698
 
699 157 khays
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
700 145 khays
  fprintf (file, _("\
701
  --stub-group-size=N         Maximum size of a group of input sections that\n\
702
                                can be handled by one stub section.  A negative\n\
703
                                value locates all stubs before their branches\n\
704
                                (with a group size of -N), while a positive\n\
705
                                value allows two groups of input sections, one\n\
706
                                before, and one after each stub section.\n\
707
                                Values of +/-1 indicate the linker should\n\
708
                                choose suitable defaults.\n"
709
                   ));
710
  fprintf (file, _("\
711 166 khays
  --plt-static-chain          PLT call stubs should load r11.${DEFAULT_PLT_STATIC_CHAIN- (default)}\n"
712 157 khays
                   ));
713
  fprintf (file, _("\
714 166 khays
  --no-plt-static-chain       PLT call stubs should not load r11.${DEFAULT_PLT_STATIC_CHAIN+ (default)}\n"
715 157 khays
                   ));
716
  fprintf (file, _("\
717 166 khays
  --plt-thread-safe           PLT call stubs with load-load barrier.\n"
718
                   ));
719
  fprintf (file, _("\
720
  --no-plt-thread-safe        PLT call stubs without barrier.\n"
721
                   ));
722
  fprintf (file, _("\
723
  --plt-align [=]      Align PLT call stubs to fit cache lines.\n"
724
                   ));
725
  fprintf (file, _("\
726
  --no-plt-align              Dont'\''t align individual PLT call stubs.\n"
727
                   ));
728
  fprintf (file, _("\
729 145 khays
  --emit-stub-syms            Label linker stubs with a symbol.\n"
730
                   ));
731
  fprintf (file, _("\
732
  --no-emit-stub-syms         Don'\''t label linker stubs with a symbol.\n"
733
                   ));
734
  fprintf (file, _("\
735
  --dotsyms                   For every version pattern \"foo\" in a version\n\
736
                                script, add \".foo\" so that function code\n\
737
                                symbols are treated the same as function\n\
738
                                descriptor symbols.  Defaults to on.\n"
739
                   ));
740
  fprintf (file, _("\
741
  --no-dotsyms                Don'\''t do anything special in version scripts.\n"
742
                   ));
743
  fprintf (file, _("\
744
  --no-tls-optimize           Don'\''t try to optimize TLS accesses.\n"
745
                   ));
746
  fprintf (file, _("\
747
  --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call.\n"
748
                   ));
749
  fprintf (file, _("\
750
  --no-opd-optimize           Don'\''t optimize the OPD section.\n"
751
                   ));
752
  fprintf (file, _("\
753
  --no-toc-optimize           Don'\''t optimize the TOC section.\n"
754
                   ));
755
  fprintf (file, _("\
756
  --no-multi-toc              Disallow automatic multiple toc sections.\n"
757
                   ));
758
  fprintf (file, _("\
759
  --no-toc-sort               Don'\''t sort TOC and GOT sections.\n"
760
                   ));
761
  fprintf (file, _("\
762
  --non-overlapping-opd       Canonicalize .opd, so that there are no\n\
763
                                overlapping .opd entries.\n"
764
                   ));
765
'
766
 
767 157 khays
PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
768 145 khays
    case OPTION_STUBGROUP_SIZE:
769
      {
770
        const char *end;
771
        group_size = bfd_scan_vma (optarg, &end, 0);
772
        if (*end)
773
          einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
774
      }
775
      break;
776
 
777 157 khays
    case OPTION_PLT_STATIC_CHAIN:
778
      plt_static_chain = 1;
779
      break;
780
 
781
    case OPTION_NO_PLT_STATIC_CHAIN:
782
      plt_static_chain = 0;
783
      break;
784
 
785 166 khays
    case OPTION_PLT_THREAD_SAFE:
786
      plt_thread_safe = 1;
787
      break;
788
 
789
    case OPTION_NO_PLT_THREAD_SAFE:
790
      plt_thread_safe = 0;
791
      break;
792
 
793
    case OPTION_PLT_ALIGN:
794
      if (optarg != NULL)
795
        {
796
          char *end;
797
          unsigned long val = strtoul (optarg, &end, 0);
798
          if (*end || val > 8)
799
            einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
800
          plt_stub_align = val;
801
        }
802
      else
803
        plt_stub_align = 5;
804
      break;
805
 
806
    case OPTION_NO_PLT_ALIGN:
807
      plt_stub_align = 0;
808
      break;
809
 
810 145 khays
    case OPTION_STUBSYMS:
811
      emit_stub_syms = 1;
812
      break;
813
 
814
    case OPTION_NO_STUBSYMS:
815
      emit_stub_syms = 0;
816
      break;
817
 
818
    case OPTION_DOTSYMS:
819
      dotsyms = 1;
820
      break;
821
 
822
    case OPTION_NO_DOTSYMS:
823
      dotsyms = 0;
824
      break;
825
 
826
    case OPTION_NO_TLS_OPT:
827
      no_tls_opt = 1;
828
      break;
829
 
830
    case OPTION_NO_TLS_GET_ADDR_OPT:
831
      no_tls_get_addr_opt = 1;
832
      break;
833
 
834
    case OPTION_NO_OPD_OPT:
835
      no_opd_opt = 1;
836
      break;
837
 
838
    case OPTION_NO_TOC_OPT:
839
      no_toc_opt = 1;
840
      break;
841
 
842
    case OPTION_NO_MULTI_TOC:
843
      no_multi_toc = 1;
844
      break;
845
 
846
    case OPTION_NO_TOC_SORT:
847
      no_toc_sort = 1;
848
      break;
849
 
850
    case OPTION_NON_OVERLAPPING_OPD:
851
      non_overlapping_opd = 1;
852
      break;
853
'
854
 
855
# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
856
#
857
LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
858
LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
859
LDEMUL_FINISH=gld${EMULATION_NAME}_finish
860
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
861
LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern

powered by: WebSVN 2.1.0

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