]> git.ipfire.org Git - thirdparty/gcc.git/blob - lto-plugin/lto-plugin.c
[Ada] Improved support for aspect alignment in CCG
[thirdparty/gcc.git] / lto-plugin / lto-plugin.c
1 /* LTO plugin for gold and/or GNU ld.
2 Copyright (C) 2009-2020 Free Software Foundation, Inc.
3 Contributed by Rafael Avila de Espindola (espindola@google.com).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
18
19 /* The plugin has only one external function: onload. Gold passes it an array of
20 function that the plugin uses to communicate back to gold.
21
22 With the functions provided by gold, the plugin can be notified when
23 gold first analyzes a file and pass a symbol table back to gold. The plugin
24 is also notified when all symbols have been read and it is time to generate
25 machine code for the necessary symbols.
26
27 More information at http://gcc.gnu.org/wiki/whopr/driver.
28
29 This plugin should be passed the lto-wrapper options and will forward them.
30 It also has options at his own:
31 -debug: Print the command line used to run lto-wrapper.
32 -nop: Instead of running lto-wrapper, pass the original to the plugin. This
33 only works if the input files are hybrid.
34 -linker-output-known: Do not determine linker output
35 -linker-output-auto-notlo-rel: Switch from rel to nolto-rel mode without
36 warning. This is used on systems like VxWorks (kernel) where the link is
37 always partial and repeated incremental linking is generally not used.
38 -sym-style={none,win32,underscore|uscore}
39 -pass-through */
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44 #if HAVE_STDINT_H
45 #include <stdint.h>
46 #endif
47 #include <stdbool.h>
48 #include <assert.h>
49 #include <errno.h>
50 #include <string.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <inttypes.h>
54 #include <sys/stat.h>
55 #include <unistd.h>
56 #include <fcntl.h>
57 #include <sys/types.h>
58 #ifdef HAVE_SYS_WAIT_H
59 #include <sys/wait.h>
60 #endif
61 #ifndef WIFEXITED
62 #define WIFEXITED(S) (((S) & 0xff) == 0)
63 #endif
64 #ifndef WEXITSTATUS
65 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
66 #endif
67 #include <libiberty.h>
68 #include <hashtab.h>
69 #include "../gcc/lto/common.h"
70 #include "simple-object.h"
71 #include "plugin-api.h"
72
73 /* We need to use I64 instead of ll width-specifier on native Windows.
74 The reason for this is that older MS-runtimes don't support the ll. */
75 #ifdef __MINGW32__
76 #define PRI_LL "I64"
77 #else
78 #define PRI_LL "ll"
79 #endif
80
81 /* Handle opening elf files on hosts, such as Windows, that may use
82 text file handling that will break binary access. */
83 #ifndef O_BINARY
84 # define O_BINARY 0
85 #endif
86
87 /* Segment name for LTO sections. This is only used for Mach-O.
88 FIXME: This needs to be kept in sync with darwin.c. */
89
90 #define LTO_SEGMENT_NAME "__GNU_LTO"
91
92 /* LTO magic section name. */
93
94 #define LTO_SYMTAB_PREFIX ".gnu.lto_.symtab"
95 #define LTO_SYMTAB_PREFIX_LEN (sizeof (LTO_SYMTAB_PREFIX) - 1)
96 #define LTO_SYMTAB_EXT_PREFIX ".gnu.lto_.ext_symtab"
97 #define LTO_SYMTAB_EXT_PREFIX_LEN (sizeof (LTO_SYMTAB_EXT_PREFIX) - 1)
98 #define LTO_LTO_PREFIX ".gnu.lto_.lto"
99 #define LTO_LTO_PREFIX_LEN (sizeof (LTO_LTO_PREFIX) - 1)
100 #define OFFLOAD_SECTION ".gnu.offload_lto_.opts"
101 #define OFFLOAD_SECTION_LEN (sizeof (OFFLOAD_SECTION) - 1)
102
103 /* The part of the symbol table the plugin has to keep track of. Note that we
104 must keep SYMS until all_symbols_read is called to give the linker time to
105 copy the symbol information.
106 The id must be 64bit to minimze collisions. */
107
108 struct sym_aux
109 {
110 uint32_t slot;
111 unsigned long long id;
112 unsigned next_conflict;
113 };
114
115 struct plugin_symtab
116 {
117 int nsyms;
118 struct sym_aux *aux;
119 struct ld_plugin_symbol *syms;
120 unsigned long long id;
121 };
122
123 /* Encapsulates object file data during symbol scan. */
124 struct plugin_objfile
125 {
126 int found;
127 int offload;
128 simple_object_read *objfile;
129 struct plugin_symtab *out;
130 const struct ld_plugin_input_file *file;
131 };
132
133 /* All that we have to remember about a file. */
134
135 struct plugin_file_info
136 {
137 char *name;
138 void *handle;
139 struct plugin_symtab symtab;
140 struct plugin_symtab conflicts;
141 };
142
143 /* List item with name of the file with offloading. */
144
145 struct plugin_offload_file
146 {
147 char *name;
148 struct plugin_offload_file *next;
149 };
150
151 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
152 stdio file streams, we do simple label translation here. */
153
154 enum symbol_style
155 {
156 ss_none, /* No underscore prefix. */
157 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
158 ss_uscore, /* Underscore prefix all symbols. */
159 };
160
161 static char *arguments_file_name;
162 static ld_plugin_register_claim_file register_claim_file;
163 static ld_plugin_register_all_symbols_read register_all_symbols_read;
164 static ld_plugin_get_symbols get_symbols, get_symbols_v2;
165 static ld_plugin_register_cleanup register_cleanup;
166 static ld_plugin_add_input_file add_input_file;
167 static ld_plugin_add_input_library add_input_library;
168 static ld_plugin_message message;
169 static ld_plugin_add_symbols add_symbols, add_symbols_v2;
170
171 static struct plugin_file_info *claimed_files = NULL;
172 static unsigned int num_claimed_files = 0;
173 static unsigned int non_claimed_files = 0;
174
175 /* List of files with offloading. */
176 static struct plugin_offload_file *offload_files;
177 /* Last file in the list. */
178 static struct plugin_offload_file *offload_files_last;
179 /* Last non-archive file in the list. */
180 static struct plugin_offload_file *offload_files_last_obj;
181 /* Last LTO file in the list. */
182 static struct plugin_offload_file *offload_files_last_lto;
183 /* Total number of files with offloading. */
184 static unsigned num_offload_files;
185
186 static char **output_files = NULL;
187 static unsigned int num_output_files = 0;
188
189 static char **lto_wrapper_argv;
190 static int lto_wrapper_num_args;
191
192 static char **pass_through_items = NULL;
193 static unsigned int num_pass_through_items;
194
195 static bool debug;
196 static bool save_temps;
197 static bool verbose;
198 static char nop;
199 static char *resolution_file = NULL;
200 static enum ld_plugin_output_file_type linker_output;
201 static bool linker_output_set;
202 static bool linker_output_known;
203 static bool linker_output_auto_nolto_rel;
204 static const char *link_output_name = NULL;
205
206 /* This indicates link_output_name already contains the dot of the
207 suffix, so we can skip it in extensions. */
208 static int skip_in_suffix = 0;
209
210 /* The version of gold being used, or -1 if not gold. The number is
211 MAJOR * 100 + MINOR. */
212 static int gold_version = -1;
213
214 /* Not used by default, but can be overridden at runtime
215 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
216 (in fact, only first letter of style arg is checked.) */
217 static enum symbol_style sym_style = ss_none;
218
219 static void
220 check_1 (int gate, enum ld_plugin_level level, const char *text)
221 {
222 if (gate)
223 return;
224
225 if (message)
226 message (level, text);
227 else
228 {
229 /* If there is no nicer way to inform the user, fallback to stderr. */
230 fprintf (stderr, "%s\n", text);
231 if (level == LDPL_FATAL)
232 abort ();
233 }
234 }
235
236 /* This little wrapper allows check to be called with a non-integer
237 first argument, such as a pointer that must be non-NULL. We can't
238 use c99 bool type to coerce it into range, so we explicitly test. */
239 #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
240
241 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
242 by P and the result is written in ENTRY. The slot number is stored in SLOT.
243 Returns the address of the next entry. */
244
245 static char *
246 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
247 struct sym_aux *aux)
248 {
249 unsigned char t;
250 enum ld_plugin_symbol_kind translate_kind[] =
251 {
252 LDPK_DEF,
253 LDPK_WEAKDEF,
254 LDPK_UNDEF,
255 LDPK_WEAKUNDEF,
256 LDPK_COMMON
257 };
258
259 enum ld_plugin_symbol_visibility translate_visibility[] =
260 {
261 LDPV_DEFAULT,
262 LDPV_PROTECTED,
263 LDPV_INTERNAL,
264 LDPV_HIDDEN
265 };
266
267 switch (sym_style)
268 {
269 case ss_win32:
270 if (p[0] == '@')
271 {
272 /* cf. Duff's device. */
273 case ss_none:
274 entry->name = xstrdup (p);
275 break;
276 }
277 /* FALL-THROUGH. */
278 case ss_uscore:
279 entry->name = concat ("_", p, NULL);
280 break;
281 default:
282 check (0, LDPL_FATAL, "invalid symbol style requested");
283 break;
284 }
285 while (*p)
286 p++;
287 p++;
288
289 entry->version = NULL;
290
291 entry->comdat_key = p;
292 while (*p)
293 p++;
294 p++;
295
296 if (strlen (entry->comdat_key) == 0)
297 entry->comdat_key = NULL;
298 else
299 entry->comdat_key = xstrdup (entry->comdat_key);
300
301 entry->unused = entry->section_kind = entry->symbol_type = 0;
302
303 t = *p;
304 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
305 entry->def = translate_kind[t];
306 p++;
307
308 t = *p;
309 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
310 entry->visibility = translate_visibility[t];
311 p++;
312
313 memcpy (&entry->size, p, sizeof (uint64_t));
314 p += 8;
315
316 memcpy (&aux->slot, p, sizeof (uint32_t));
317 p += 4;
318
319 entry->resolution = LDPR_UNKNOWN;
320
321 aux->next_conflict = -1;
322
323 return p;
324 }
325
326 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
327 by P and the result is written in ENTRY. The slot number is stored in SLOT.
328 Returns the address of the next entry. */
329
330 static char *
331 parse_table_entry_extension (char *p, struct ld_plugin_symbol *entry)
332 {
333 unsigned char t;
334 enum ld_plugin_symbol_type symbol_types[] =
335 {
336 LDST_UNKNOWN,
337 LDST_FUNCTION,
338 LDST_VARIABLE,
339 };
340
341 t = *p;
342 check (t <= 2, LDPL_FATAL, "invalid symbol type found");
343 entry->symbol_type = symbol_types[t];
344 p++;
345 entry->section_kind = *p;
346 p++;
347
348 return p;
349 }
350
351
352 /* Translate the IL symbol table located between DATA and END. Append the
353 slots and symbols to OUT. */
354
355 static void
356 translate (char *data, char *end, struct plugin_symtab *out)
357 {
358 struct sym_aux *aux;
359 struct ld_plugin_symbol *syms = NULL;
360 int n, len;
361
362 /* This overestimates the output buffer sizes, but at least
363 the algorithm is O(1) now. */
364
365 len = (end - data)/8 + out->nsyms + 1;
366 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
367 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
368
369 for (n = out->nsyms; data < end; n++)
370 {
371 aux[n].id = out->id;
372 data = parse_table_entry (data, &syms[n], &aux[n]);
373 }
374
375 assert(n < len);
376
377 out->nsyms = n;
378 out->syms = syms;
379 out->aux = aux;
380 }
381
382 static void
383 parse_symtab_extension (char *data, char *end, struct plugin_symtab *out)
384 {
385 unsigned i;
386
387 unsigned char version = *data;
388 data++;
389
390 /* Version 1 contains the following data per entry:
391 - symbol_type
392 - section_kind
393 . */
394
395 if (version == 1)
396 for (i = 0; i < out->nsyms; i++)
397 data = parse_table_entry_extension (data, &out->syms[i]);
398 }
399
400 /* Free all memory that is no longer needed after writing the symbol
401 resolution. */
402
403 static void
404 free_1 (struct plugin_file_info *files, unsigned num_files)
405 {
406 unsigned int i;
407 for (i = 0; i < num_files; i++)
408 {
409 struct plugin_file_info *info = &files[i];
410 struct plugin_symtab *symtab = &info->symtab;
411 unsigned int j;
412 for (j = 0; j < symtab->nsyms; j++)
413 {
414 struct ld_plugin_symbol *s = &symtab->syms[j];
415 free (s->name);
416 free (s->comdat_key);
417 }
418 free (symtab->syms);
419 symtab->syms = NULL;
420 }
421 }
422
423 /* Free all remaining memory. */
424
425 static void
426 free_2 (void)
427 {
428 unsigned int i;
429 for (i = 0; i < num_claimed_files; i++)
430 {
431 struct plugin_file_info *info = &claimed_files[i];
432 struct plugin_symtab *symtab = &info->symtab;
433 free (symtab->aux);
434 free (info->name);
435 }
436
437 for (i = 0; i < num_output_files; i++)
438 free (output_files[i]);
439 free (output_files);
440
441 free (claimed_files);
442 claimed_files = NULL;
443 num_claimed_files = 0;
444
445 while (offload_files)
446 {
447 struct plugin_offload_file *ofld = offload_files;
448 offload_files = offload_files->next;
449 free (ofld);
450 }
451 num_offload_files = 0;
452
453 free (arguments_file_name);
454 arguments_file_name = NULL;
455 }
456
457 /* Dump SYMTAB to resolution file F. */
458
459 static void
460 dump_symtab (FILE *f, struct plugin_symtab *symtab)
461 {
462 unsigned j;
463
464 for (j = 0; j < symtab->nsyms; j++)
465 {
466 uint32_t slot = symtab->aux[j].slot;
467 unsigned int resolution = symtab->syms[j].resolution;
468
469 assert (resolution != LDPR_UNKNOWN);
470
471 fprintf (f, "%u %" PRI_LL "x %s %s\n",
472 (unsigned int) slot, symtab->aux[j].id,
473 lto_resolution_str[resolution],
474 symtab->syms[j].name);
475 }
476 }
477
478 /* Finish the conflicts' resolution information after the linker resolved
479 the original symbols */
480
481 static void
482 finish_conflict_resolution (struct plugin_symtab *symtab,
483 struct plugin_symtab *conflicts)
484 {
485 int i, j;
486
487 if (conflicts->nsyms == 0)
488 return;
489
490 for (i = 0; i < symtab->nsyms; i++)
491 {
492 char resolution = LDPR_UNKNOWN;
493
494 if (symtab->aux[i].next_conflict == -1)
495 continue;
496
497 switch (symtab->syms[i].def)
498 {
499 case LDPK_DEF:
500 case LDPK_COMMON: /* ??? */
501 resolution = LDPR_RESOLVED_IR;
502 break;
503 case LDPK_WEAKDEF:
504 resolution = LDPR_PREEMPTED_IR;
505 break;
506 case LDPK_UNDEF:
507 case LDPK_WEAKUNDEF:
508 resolution = symtab->syms[i].resolution;
509 break;
510 default:
511 assert (0);
512 }
513
514 assert (resolution != LDPR_UNKNOWN);
515
516 for (j = symtab->aux[i].next_conflict;
517 j != -1;
518 j = conflicts->aux[j].next_conflict)
519 conflicts->syms[j].resolution = resolution;
520 }
521 }
522
523 /* Free symbol table SYMTAB. */
524
525 static void
526 free_symtab (struct plugin_symtab *symtab)
527 {
528 free (symtab->syms);
529 symtab->syms = NULL;
530 free (symtab->aux);
531 symtab->aux = NULL;
532 }
533
534 /* Writes the relocations to disk. */
535
536 static void
537 write_resolution (void)
538 {
539 unsigned int i;
540 FILE *f;
541
542 check (resolution_file, LDPL_FATAL, "resolution file not specified");
543 f = fopen (resolution_file, "w");
544 check (f, LDPL_FATAL, "could not open file");
545
546 fprintf (f, "%d\n", num_claimed_files);
547
548 for (i = 0; i < num_claimed_files; i++)
549 {
550 struct plugin_file_info *info = &claimed_files[i];
551 struct plugin_symtab *symtab = &info->symtab;
552 struct ld_plugin_symbol *syms = symtab->syms;
553
554 /* Version 2 of API supports IRONLY_EXP resolution that is
555 accepted by GCC-4.7 and newer. */
556 if (get_symbols_v2)
557 get_symbols_v2 (info->handle, symtab->nsyms, syms);
558 else
559 get_symbols (info->handle, symtab->nsyms, syms);
560
561 finish_conflict_resolution (symtab, &info->conflicts);
562
563 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
564 dump_symtab (f, symtab);
565 if (info->conflicts.nsyms)
566 {
567 dump_symtab (f, &info->conflicts);
568 free_symtab (&info->conflicts);
569 }
570 }
571 fclose (f);
572 }
573
574 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
575 stdout. */
576
577 static void
578 add_output_files (FILE *f)
579 {
580 for (;;)
581 {
582 const unsigned piece = 32;
583 char *buf, *s = xmalloc (piece);
584 size_t len;
585
586 buf = s;
587 cont:
588 if (!fgets (buf, piece, f))
589 {
590 free (s);
591 break;
592 }
593 len = strlen (s);
594 if (s[len - 1] != '\n')
595 {
596 s = xrealloc (s, len + piece);
597 buf = s + len;
598 goto cont;
599 }
600 s[len - 1] = '\0';
601
602 num_output_files++;
603 output_files
604 = xrealloc (output_files, num_output_files * sizeof (char *));
605 output_files[num_output_files - 1] = s;
606 add_input_file (output_files[num_output_files - 1]);
607 }
608 }
609
610 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
611 argument list. */
612
613 static void
614 exec_lto_wrapper (char *argv[])
615 {
616 int t, i;
617 int status;
618 char *at_args;
619 FILE *args;
620 FILE *wrapper_output;
621 char *new_argv[3];
622 struct pex_obj *pex;
623 const char *errmsg;
624
625 /* Write argv to a file to avoid a command line that is too long
626 Save the file locally on save-temps. */
627 if (save_temps && link_output_name)
628 arguments_file_name = concat (link_output_name,
629 ".lto_wrapper_args"
630 + skip_in_suffix, NULL);
631 else
632 arguments_file_name = make_temp_file (".lto_wrapper_args");
633 check (arguments_file_name, LDPL_FATAL,
634 "Failed to generate a temorary file name");
635
636 args = fopen (arguments_file_name, "w");
637 check (args, LDPL_FATAL, "could not open arguments file");
638
639 t = writeargv (&argv[1], args);
640 check (t == 0, LDPL_FATAL, "could not write arguments");
641 t = fclose (args);
642 check (t == 0, LDPL_FATAL, "could not close arguments file");
643
644 at_args = concat ("@", arguments_file_name, NULL);
645 check (at_args, LDPL_FATAL, "could not allocate");
646
647 for (i = 1; argv[i]; i++)
648 {
649 char *a = argv[i];
650 /* Check the input argument list for a verbose marker too. */
651 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
652 {
653 verbose = true;
654 break;
655 }
656 }
657
658 if (verbose)
659 {
660 for (i = 0; argv[i]; i++)
661 fprintf (stderr, "%s ", argv[i]);
662 fprintf (stderr, "\n");
663 }
664
665 new_argv[0] = argv[0];
666 new_argv[1] = at_args;
667 new_argv[2] = NULL;
668
669 if (debug)
670 {
671 for (i = 0; new_argv[i]; i++)
672 fprintf (stderr, "%s ", new_argv[i]);
673 fprintf (stderr, "\n");
674 }
675
676 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
677 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
678
679 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
680 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
681 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
682
683 wrapper_output = pex_read_output (pex, 0);
684 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
685
686 add_output_files (wrapper_output);
687
688 t = pex_get_status (pex, 1, &status);
689 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
690 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
691 "lto-wrapper failed");
692
693 pex_free (pex);
694
695 free (at_args);
696 }
697
698 /* Pass the original files back to the linker. */
699
700 static void
701 use_original_files (void)
702 {
703 unsigned i;
704 for (i = 0; i < num_claimed_files; i++)
705 {
706 struct plugin_file_info *info = &claimed_files[i];
707 add_input_file (info->name);
708 }
709 }
710
711
712 /* Called by the linker once all symbols have been read. */
713
714 static enum ld_plugin_status
715 all_symbols_read_handler (void)
716 {
717 const unsigned num_lto_args
718 = num_claimed_files + lto_wrapper_num_args + 2
719 + !linker_output_known + !linker_output_auto_nolto_rel;
720 unsigned i;
721 char **lto_argv;
722 const char *linker_output_str = NULL;
723 const char **lto_arg_ptr;
724 if (num_claimed_files + num_offload_files == 0)
725 return LDPS_OK;
726
727 if (nop)
728 {
729 use_original_files ();
730 return LDPS_OK;
731 }
732
733 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
734 lto_arg_ptr = (const char **) lto_argv;
735 assert (lto_wrapper_argv);
736
737 write_resolution ();
738
739 free_1 (claimed_files, num_claimed_files);
740
741 for (i = 0; i < lto_wrapper_num_args; i++)
742 *lto_arg_ptr++ = lto_wrapper_argv[i];
743
744 if (!linker_output_known)
745 {
746 assert (linker_output_set);
747 switch (linker_output)
748 {
749 case LDPO_REL:
750 if (non_claimed_files)
751 {
752 if (!linker_output_auto_nolto_rel)
753 message (LDPL_WARNING, "incremental linking of LTO and non-LTO"
754 " objects; using -flinker-output=nolto-rel which will"
755 " bypass whole program optimization");
756 linker_output_str = "-flinker-output=nolto-rel";
757 }
758 else
759 linker_output_str = "-flinker-output=rel";
760 break;
761 case LDPO_DYN:
762 linker_output_str = "-flinker-output=dyn";
763 break;
764 case LDPO_PIE:
765 linker_output_str = "-flinker-output=pie";
766 break;
767 case LDPO_EXEC:
768 linker_output_str = "-flinker-output=exec";
769 break;
770 default:
771 message (LDPL_FATAL, "unsupported linker output %i", linker_output);
772 break;
773 }
774 *lto_arg_ptr++ = xstrdup (linker_output_str);
775 }
776
777 if (num_offload_files > 0)
778 {
779 FILE *f;
780 char *arg;
781 char *offload_objects_file_name;
782 struct plugin_offload_file *ofld;
783
784 offload_objects_file_name = make_temp_file (".ofldlist");
785 check (offload_objects_file_name, LDPL_FATAL,
786 "Failed to generate a temporary file name");
787 f = fopen (offload_objects_file_name, "w");
788 check (f, LDPL_FATAL, "could not open file with offload objects");
789 fprintf (f, "%u\n", num_offload_files);
790
791 /* Skip the dummy item at the start of the list. */
792 ofld = offload_files->next;
793 while (ofld)
794 {
795 fprintf (f, "%s\n", ofld->name);
796 ofld = ofld->next;
797 }
798 fclose (f);
799
800 arg = concat ("-foffload-objects=", offload_objects_file_name, NULL);
801 check (arg, LDPL_FATAL, "could not allocate");
802 *lto_arg_ptr++ = arg;
803 }
804
805 for (i = 0; i < num_claimed_files; i++)
806 {
807 struct plugin_file_info *info = &claimed_files[i];
808
809 *lto_arg_ptr++ = info->name;
810 }
811
812 *lto_arg_ptr++ = NULL;
813 exec_lto_wrapper (lto_argv);
814
815 free (lto_argv);
816
817 /* --pass-through is not needed when using gold 1.11 or later. */
818 if (pass_through_items && gold_version < 111)
819 {
820 unsigned int i;
821 for (i = 0; i < num_pass_through_items; i++)
822 {
823 if (strncmp (pass_through_items[i], "-l", 2) == 0)
824 add_input_library (pass_through_items[i] + 2);
825 else
826 add_input_file (pass_through_items[i]);
827 free (pass_through_items[i]);
828 pass_through_items[i] = NULL;
829 }
830 free (pass_through_items);
831 pass_through_items = NULL;
832 }
833
834 return LDPS_OK;
835 }
836
837 /* Helper, as used in collect2. */
838 static int
839 file_exists (const char *name)
840 {
841 return access (name, R_OK) == 0;
842 }
843
844 /* Unlink FILE unless we have save-temps set.
845 Note that we're saving files if verbose output is set. */
846
847 static void
848 maybe_unlink (const char *file)
849 {
850 if (save_temps && file_exists (file))
851 {
852 if (verbose)
853 fprintf (stderr, "[Leaving %s]\n", file);
854 return;
855 }
856
857 unlink_if_ordinary (file);
858 }
859
860 /* Remove temporary files at the end of the link. */
861
862 static enum ld_plugin_status
863 cleanup_handler (void)
864 {
865 unsigned int i;
866
867 if (debug)
868 return LDPS_OK;
869
870 if (arguments_file_name)
871 maybe_unlink (arguments_file_name);
872
873 for (i = 0; i < num_output_files; i++)
874 maybe_unlink (output_files[i]);
875
876 free_2 ();
877 return LDPS_OK;
878 }
879
880 #define SWAP(type, a, b) \
881 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
882
883 /* Compare two hash table entries */
884
885 static int eq_sym (const void *a, const void *b)
886 {
887 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
888 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
889
890 return !strcmp (as->name, bs->name);
891 }
892
893 /* Hash a symbol */
894
895 static hashval_t hash_sym (const void *a)
896 {
897 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
898
899 return htab_hash_string (as->name);
900 }
901
902 /* Determine how strong a symbol is */
903
904 static int symbol_strength (struct ld_plugin_symbol *s)
905 {
906 switch (s->def)
907 {
908 case LDPK_UNDEF:
909 case LDPK_WEAKUNDEF:
910 return 0;
911 case LDPK_WEAKDEF:
912 return 1;
913 default:
914 return 2;
915 }
916 }
917
918 /* In the ld -r case we can get dups in the LTO symbol tables, where
919 the same symbol can have different resolutions (e.g. undefined and defined).
920
921 We have to keep that in the LTO symbol tables, but the dups confuse
922 gold and then finally gcc by supplying incorrect resolutions.
923
924 Problem is that the main gold symbol table doesn't know about subids
925 and does not distingush the same symbols in different states.
926
927 So we drop duplicates from the linker visible symbol table
928 and keep them in a private table. Then later do own symbol
929 resolution for the duplicated based on the results for the
930 originals.
931
932 Then when writing out the resolution file readd the dropped symbols.
933
934 XXX how to handle common? */
935
936 static void
937 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
938 {
939 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
940 int i;
941 int out;
942 int outlen;
943
944 outlen = t->nsyms;
945 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
946 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
947
948 /* Move all duplicate symbols into the auxiliary conflicts table. */
949 out = 0;
950 for (i = 0; i < t->nsyms; i++)
951 {
952 struct ld_plugin_symbol *s = &t->syms[i];
953 struct sym_aux *aux = &t->aux[i];
954 void **slot;
955
956 slot = htab_find_slot (symtab, s, INSERT);
957 if (*slot != NULL)
958 {
959 int cnf;
960 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
961 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
962
963 /* Always let the linker resolve the strongest symbol */
964 if (symbol_strength (orig) < symbol_strength (s))
965 {
966 SWAP (struct ld_plugin_symbol, *orig, *s);
967 SWAP (uint32_t, orig_aux->slot, aux->slot);
968 SWAP (unsigned long long, orig_aux->id, aux->id);
969 /* Don't swap conflict chain pointer */
970 }
971
972 /* Move current symbol into the conflicts table */
973 cnf = conflicts->nsyms++;
974 conflicts->syms[cnf] = *s;
975 conflicts->aux[cnf] = *aux;
976 aux = &conflicts->aux[cnf];
977
978 /* Update conflicts chain of the original symbol */
979 aux->next_conflict = orig_aux->next_conflict;
980 orig_aux->next_conflict = cnf;
981
982 continue;
983 }
984
985 /* Remove previous duplicates in the main table */
986 if (out < i)
987 {
988 t->syms[out] = *s;
989 t->aux[out] = *aux;
990 }
991
992 /* Put original into the hash table */
993 *slot = &t->syms[out];
994 out++;
995 }
996
997 assert (conflicts->nsyms <= outlen);
998 assert (conflicts->nsyms + out == t->nsyms);
999
1000 t->nsyms = out;
1001 htab_delete (symtab);
1002 }
1003
1004 /* Process one section of an object file. */
1005
1006 static int
1007 process_symtab (void *data, const char *name, off_t offset, off_t length)
1008 {
1009 struct plugin_objfile *obj = (struct plugin_objfile *)data;
1010 char *s;
1011 char *secdatastart, *secdata;
1012
1013 if (strncmp (name, LTO_SYMTAB_PREFIX, LTO_SYMTAB_PREFIX_LEN) != 0)
1014 return 1;
1015
1016 s = strrchr (name, '.');
1017 if (s)
1018 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
1019 secdata = secdatastart = xmalloc (length);
1020 offset += obj->file->offset;
1021 if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1022 goto err;
1023
1024 do
1025 {
1026 ssize_t got = read (obj->file->fd, secdata, length);
1027 if (got == 0)
1028 break;
1029 else if (got > 0)
1030 {
1031 secdata += got;
1032 length -= got;
1033 }
1034 else if (errno != EINTR)
1035 goto err;
1036 }
1037 while (length > 0);
1038 if (length > 0)
1039 goto err;
1040
1041 translate (secdatastart, secdata, obj->out);
1042 obj->found++;
1043 free (secdatastart);
1044 return 1;
1045
1046 err:
1047 if (message)
1048 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
1049 /* Force claim_file_handler to abandon this file. */
1050 obj->found = 0;
1051 free (secdatastart);
1052 return 0;
1053 }
1054
1055 /* Process one section of an object file. */
1056
1057 static int
1058 process_symtab_extension (void *data, const char *name, off_t offset,
1059 off_t length)
1060 {
1061 struct plugin_objfile *obj = (struct plugin_objfile *)data;
1062 char *s;
1063 char *secdatastart, *secdata;
1064
1065 if (strncmp (name, LTO_SYMTAB_EXT_PREFIX, LTO_SYMTAB_EXT_PREFIX_LEN) != 0)
1066 return 1;
1067
1068 s = strrchr (name, '.');
1069 if (s)
1070 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
1071 secdata = secdatastart = xmalloc (length);
1072 offset += obj->file->offset;
1073 if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1074 goto err;
1075
1076 do
1077 {
1078 ssize_t got = read (obj->file->fd, secdata, length);
1079 if (got == 0)
1080 break;
1081 else if (got > 0)
1082 {
1083 secdata += got;
1084 length -= got;
1085 }
1086 else if (errno != EINTR)
1087 goto err;
1088 }
1089 while (length > 0);
1090 if (length > 0)
1091 goto err;
1092
1093 parse_symtab_extension (secdatastart, secdata, obj->out);
1094 obj->found++;
1095 free (secdatastart);
1096 return 1;
1097
1098 err:
1099 if (message)
1100 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
1101 /* Force claim_file_handler to abandon this file. */
1102 obj->found = 0;
1103 free (secdatastart);
1104 return 0;
1105 }
1106
1107
1108 /* Find an offload section of an object file. */
1109
1110 static int
1111 process_offload_section (void *data, const char *name, off_t offset, off_t len)
1112 {
1113 if (!strncmp (name, OFFLOAD_SECTION, OFFLOAD_SECTION_LEN))
1114 {
1115 struct plugin_objfile *obj = (struct plugin_objfile *) data;
1116 obj->offload = 1;
1117 return 0;
1118 }
1119
1120 return 1;
1121 }
1122
1123 /* Callback used by gold to check if the plugin will claim FILE. Writes
1124 the result in CLAIMED. */
1125
1126 static enum ld_plugin_status
1127 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
1128 {
1129 enum ld_plugin_status status;
1130 struct plugin_objfile obj;
1131 struct plugin_file_info lto_file;
1132 int err;
1133 const char *errmsg;
1134
1135 memset (&lto_file, 0, sizeof (struct plugin_file_info));
1136
1137 if (file->offset != 0)
1138 {
1139 /* We pass the offset of the actual file, not the archive header.
1140 Can't use PRIx64, because that's C99, so we have to print the
1141 64-bit hex int as two 32-bit ones. Use xasprintf instead of
1142 asprintf because asprintf doesn't work as expected on some older
1143 mingw32 hosts. */
1144 int lo, hi;
1145 lo = file->offset & 0xffffffff;
1146 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
1147 lto_file.name = hi ? xasprintf ("%s@0x%x%08x", file->name, hi, lo)
1148 : xasprintf ("%s@0x%x", file->name, lo);
1149 }
1150 else
1151 {
1152 lto_file.name = xstrdup (file->name);
1153 }
1154 lto_file.handle = file->handle;
1155
1156 *claimed = 0;
1157 obj.file = file;
1158 obj.found = 0;
1159 obj.offload = 0;
1160 obj.out = &lto_file.symtab;
1161 errmsg = NULL;
1162 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
1163 &errmsg, &err);
1164 /* No file, but also no error code means unrecognized format; just skip it. */
1165 if (!obj.objfile && !err)
1166 goto err;
1167
1168 if (obj.objfile)
1169 {
1170 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj,
1171 &err);
1172 /* Parsing symtab extension should be done only for add_symbols_v2 and
1173 later versions. */
1174 if (!errmsg && add_symbols_v2 != NULL)
1175 errmsg = simple_object_find_sections (obj.objfile,
1176 process_symtab_extension,
1177 &obj, &err);
1178 }
1179
1180 if (!obj.objfile || errmsg)
1181 {
1182 if (err && message)
1183 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
1184 xstrerror (err));
1185 else if (message)
1186 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
1187 goto err;
1188 }
1189
1190 if (obj.objfile)
1191 simple_object_find_sections (obj.objfile, process_offload_section,
1192 &obj, &err);
1193
1194 if (obj.found == 0 && obj.offload == 0)
1195 goto err;
1196
1197 if (obj.found > 1)
1198 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
1199
1200 if (obj.found > 0)
1201 {
1202 if (add_symbols_v2)
1203 status = add_symbols_v2 (file->handle, lto_file.symtab.nsyms,
1204 lto_file.symtab.syms);
1205 else
1206 status = add_symbols (file->handle, lto_file.symtab.nsyms,
1207 lto_file.symtab.syms);
1208 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
1209
1210 num_claimed_files++;
1211 claimed_files =
1212 xrealloc (claimed_files,
1213 num_claimed_files * sizeof (struct plugin_file_info));
1214 claimed_files[num_claimed_files - 1] = lto_file;
1215
1216 *claimed = 1;
1217 }
1218
1219 if (offload_files == NULL)
1220 {
1221 /* Add dummy item to the start of the list. */
1222 offload_files = xmalloc (sizeof (struct plugin_offload_file));
1223 offload_files->name = NULL;
1224 offload_files->next = NULL;
1225 offload_files_last = offload_files;
1226 }
1227
1228 /* If this is an LTO file without offload, and it is the first LTO file, save
1229 the pointer to the last offload file in the list. Further offload LTO
1230 files will be inserted after it, if any. */
1231 if (*claimed && obj.offload == 0 && offload_files_last_lto == NULL)
1232 offload_files_last_lto = offload_files_last;
1233
1234 if (obj.offload == 1)
1235 {
1236 /* Add file to the list. The order must be exactly the same as the final
1237 order after recompilation and linking, otherwise host and target tables
1238 with addresses wouldn't match. If a static library contains both LTO
1239 and non-LTO objects, ld and gold link them in a different order. */
1240 struct plugin_offload_file *ofld
1241 = xmalloc (sizeof (struct plugin_offload_file));
1242 ofld->name = lto_file.name;
1243 ofld->next = NULL;
1244
1245 if (*claimed && offload_files_last_lto == NULL && file->offset != 0
1246 && gold_version == -1)
1247 {
1248 /* ld only: insert first LTO file from the archive after the last real
1249 object file immediately preceding the archive, or at the begin of
1250 the list if there was no real objects before archives. */
1251 if (offload_files_last_obj != NULL)
1252 {
1253 ofld->next = offload_files_last_obj->next;
1254 offload_files_last_obj->next = ofld;
1255 }
1256 else
1257 {
1258 ofld->next = offload_files->next;
1259 offload_files->next = ofld;
1260 }
1261 }
1262 else if (*claimed && offload_files_last_lto != NULL)
1263 {
1264 /* Insert LTO file after the last LTO file in the list. */
1265 ofld->next = offload_files_last_lto->next;
1266 offload_files_last_lto->next = ofld;
1267 }
1268 else
1269 /* Add non-LTO file or first non-archive LTO file to the end of the
1270 list. */
1271 offload_files_last->next = ofld;
1272
1273 if (ofld->next == NULL)
1274 offload_files_last = ofld;
1275 if (file->offset == 0)
1276 offload_files_last_obj = ofld;
1277 if (*claimed)
1278 offload_files_last_lto = ofld;
1279 num_offload_files++;
1280 }
1281
1282 goto cleanup;
1283
1284 err:
1285 non_claimed_files++;
1286 free (lto_file.name);
1287
1288 cleanup:
1289 if (obj.objfile)
1290 simple_object_release_read (obj.objfile);
1291
1292 return LDPS_OK;
1293 }
1294
1295 /* Parse the plugin options. */
1296
1297 static void
1298 process_option (const char *option)
1299 {
1300 if (strcmp (option, "-linker-output-known") == 0)
1301 linker_output_known = true;
1302 else if (strcmp (option, "-linker-output-auto-notlo-rel") == 0)
1303 linker_output_auto_nolto_rel = true;
1304 else if (strcmp (option, "-debug") == 0)
1305 debug = true;
1306 else if ((strcmp (option, "-v") == 0)
1307 || (strcmp (option, "--verbose") == 0))
1308 verbose = true;
1309 else if (strcmp (option, "-save-temps") == 0)
1310 save_temps = true;
1311 else if (strcmp (option, "-nop") == 0)
1312 nop = 1;
1313 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
1314 {
1315 num_pass_through_items++;
1316 pass_through_items = xrealloc (pass_through_items,
1317 num_pass_through_items * sizeof (char *));
1318 pass_through_items[num_pass_through_items - 1] =
1319 xstrdup (option + strlen ("-pass-through="));
1320 }
1321 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
1322 {
1323 switch (option[sizeof ("-sym-style=") - 1])
1324 {
1325 case 'w':
1326 sym_style = ss_win32;
1327 break;
1328 case 'u':
1329 sym_style = ss_uscore;
1330 break;
1331 default:
1332 sym_style = ss_none;
1333 break;
1334 }
1335 }
1336 else
1337 {
1338 int size;
1339 char *opt = xstrdup (option);
1340 lto_wrapper_num_args += 1;
1341 size = lto_wrapper_num_args * sizeof (char *);
1342 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
1343 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
1344 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
1345 resolution_file = opt + sizeof ("-fresolution=") - 1;
1346 }
1347 save_temps = save_temps || debug;
1348 verbose = verbose || debug;
1349 }
1350
1351 /* Called by gold after loading the plugin. TV is the transfer vector. */
1352
1353 enum ld_plugin_status
1354 onload (struct ld_plugin_tv *tv)
1355 {
1356 struct ld_plugin_tv *p;
1357 enum ld_plugin_status status;
1358
1359 p = tv;
1360 while (p->tv_tag)
1361 {
1362 switch (p->tv_tag)
1363 {
1364 case LDPT_MESSAGE:
1365 message = p->tv_u.tv_message;
1366 break;
1367 case LDPT_REGISTER_CLAIM_FILE_HOOK:
1368 register_claim_file = p->tv_u.tv_register_claim_file;
1369 break;
1370 case LDPT_ADD_SYMBOLS_V2:
1371 add_symbols_v2 = p->tv_u.tv_add_symbols;
1372 break;
1373 case LDPT_ADD_SYMBOLS:
1374 add_symbols = p->tv_u.tv_add_symbols;
1375 break;
1376 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1377 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
1378 break;
1379 case LDPT_GET_SYMBOLS_V2:
1380 get_symbols_v2 = p->tv_u.tv_get_symbols;
1381 break;
1382 case LDPT_GET_SYMBOLS:
1383 get_symbols = p->tv_u.tv_get_symbols;
1384 break;
1385 case LDPT_REGISTER_CLEANUP_HOOK:
1386 register_cleanup = p->tv_u.tv_register_cleanup;
1387 break;
1388 case LDPT_ADD_INPUT_FILE:
1389 add_input_file = p->tv_u.tv_add_input_file;
1390 break;
1391 case LDPT_ADD_INPUT_LIBRARY:
1392 add_input_library = p->tv_u.tv_add_input_library;
1393 break;
1394 case LDPT_OPTION:
1395 process_option (p->tv_u.tv_string);
1396 break;
1397 case LDPT_GOLD_VERSION:
1398 gold_version = p->tv_u.tv_val;
1399 break;
1400 case LDPT_LINKER_OUTPUT:
1401 linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
1402 linker_output_set = true;
1403 break;
1404 case LDPT_OUTPUT_NAME:
1405 /* We only use this to make user-friendly temp file names. */
1406 link_output_name = p->tv_u.tv_string;
1407 break;
1408 default:
1409 break;
1410 }
1411 p++;
1412 }
1413
1414 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1415 check (add_symbols, LDPL_FATAL, "add_symbols not found");
1416 status = register_claim_file (claim_file_handler);
1417 check (status == LDPS_OK, LDPL_FATAL,
1418 "could not register the claim_file callback");
1419
1420 if (register_cleanup)
1421 {
1422 status = register_cleanup (cleanup_handler);
1423 check (status == LDPS_OK, LDPL_FATAL,
1424 "could not register the cleanup callback");
1425 }
1426
1427 if (register_all_symbols_read)
1428 {
1429 check (get_symbols, LDPL_FATAL, "get_symbols not found");
1430 status = register_all_symbols_read (all_symbols_read_handler);
1431 check (status == LDPS_OK, LDPL_FATAL,
1432 "could not register the all_symbols_read callback");
1433 }
1434
1435 char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
1436 if (collect_gcc_options)
1437 {
1438 /* Support -fno-use-linker-plugin by failing to load the plugin
1439 for the case where it is auto-loaded by BFD. */
1440 if (strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
1441 return LDPS_ERR;
1442
1443 if (strstr (collect_gcc_options, "'-save-temps'"))
1444 save_temps = true;
1445
1446 if (strstr (collect_gcc_options, "'-v'")
1447 || strstr (collect_gcc_options, "'--verbose'"))
1448 verbose = true;
1449
1450 const char *p;
1451 if ((p = strstr (collect_gcc_options, "'-dumpdir'")))
1452 {
1453 p += sizeof ("'-dumpdir'");
1454 while (*p == ' ')
1455 p++;
1456 const char *start = p;
1457 int ticks = 0, escapes = 0;
1458 /* Count ticks (') and escaped (\.) characters. Stop at the
1459 end of the options or at a blank after an even number of
1460 ticks (not counting escaped ones. */
1461 for (p = start; *p; p++)
1462 {
1463 if (*p == '\'')
1464 {
1465 ticks++;
1466 continue;
1467 }
1468 else if ((ticks % 2) != 0)
1469 {
1470 if (*p == ' ')
1471 break;
1472 if (*p == '\\')
1473 {
1474 if (*++p)
1475 escapes++;
1476 else
1477 p--;
1478 }
1479 }
1480 }
1481
1482 /* Now allocate a new link_output_name and decode dumpdir
1483 into it. The loop uses the same logic, except it counts
1484 ticks and escapes backwards (so ticks is adjusted if we
1485 find an odd number of them), and it copies characters
1486 that are escaped or not otherwise skipped. */
1487 int len = p - start - ticks - escapes + 1;
1488 char *q = xmalloc (len);
1489 link_output_name = q;
1490 int oddticks = (ticks % 2);
1491 ticks += oddticks;
1492 for (p = start; *p; p++)
1493 {
1494 if (*p == '\'')
1495 {
1496 ticks--;
1497 continue;
1498 }
1499 else if ((ticks % 2) != 0)
1500 {
1501 if (*p == ' ')
1502 break;
1503 if (*p == '\\')
1504 {
1505 if (*++p)
1506 escapes--;
1507 else
1508 p--;
1509 }
1510 }
1511 *q++ = *p;
1512 }
1513 *q = '\0';
1514 assert (escapes == 0);
1515 assert (ticks == oddticks);
1516 assert (q - link_output_name == len - 1);
1517 skip_in_suffix = 1;
1518 }
1519 }
1520
1521 return LDPS_OK;
1522 }