1 /* LTO plugin for gold.
2 Copyright (C) 2009 Free Software Foundation, Inc.
3 Contributed by Rafael Avila de Espindola (espindola@google.com).
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)
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.
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/>. */
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.
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.
27 More information at http://gcc.gnu.org/wiki/whopr/driver.
29 This plugin should be passed the lto-wrapper options and will forward them.
30 It also has 2 options of its 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. */
44 #include <sys/types.h>
47 #include <libiberty.h>
49 /* The presence of gelf.h is checked by the toplevel configure script. */
52 #include "plugin-api.h"
53 #include "../gcc/lto/common.h"
55 /* The part of the symbol table the plugin has to keep track of. Note that we
56 must keep SYMS until all_symbols_read is called to give the linker time to
57 copy the symbol information. */
63 struct ld_plugin_symbol
*syms
;
66 /* All that we have to remember about a file. */
68 struct plugin_file_info
72 struct plugin_symtab symtab
;
77 static char *temp_obj_dir_name
;
78 static ld_plugin_register_claim_file register_claim_file
;
79 static ld_plugin_add_symbols add_symbols
;
80 static ld_plugin_register_all_symbols_read register_all_symbols_read
;
81 static ld_plugin_get_symbols get_symbols
;
82 static ld_plugin_register_cleanup register_cleanup
;
83 static ld_plugin_add_input_file add_input_file
;
84 static ld_plugin_add_input_library add_input_library
;
86 static struct plugin_file_info
*claimed_files
= NULL
;
87 static unsigned int num_claimed_files
= 0;
89 static char **output_files
= NULL
;
90 static unsigned int num_output_files
= 0;
92 static char **lto_wrapper_argv
;
93 static int lto_wrapper_num_args
;
95 static char **pass_through_items
= NULL
;
96 static unsigned int num_pass_through_items
;
100 static char *resolution_file
= NULL
;
102 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
103 by P and the result is written in ENTRY. The slot number is stored in SLOT.
104 Returns the address of the next entry. */
107 parse_table_entry (char *p
, struct ld_plugin_symbol
*entry
, uint32_t *slot
)
110 enum ld_plugin_symbol_kind translate_kind
[] =
119 enum ld_plugin_symbol_visibility translate_visibility
[] =
127 entry
->name
= strdup (p
);
132 entry
->version
= NULL
;
134 entry
->comdat_key
= p
;
139 if (strlen (entry
->comdat_key
) == 0)
140 entry
->comdat_key
= NULL
;
142 entry
->comdat_key
= strdup (entry
->comdat_key
);
146 entry
->def
= translate_kind
[t
];
151 entry
->visibility
= translate_visibility
[t
];
154 entry
->size
= *(uint64_t *) p
;
157 *slot
= *(uint32_t *) p
;
160 entry
->resolution
= LDPR_UNKNOWN
;
165 /* Return the section in ELF that is named NAME. */
168 get_section (Elf
*elf
, const char *name
)
170 Elf_Scn
*section
= 0;
172 GElf_Ehdr
*t
= gelf_getehdr (elf
, &header
);
175 assert (t
== &header
);
177 while ((section
= elf_nextscn(elf
, section
)) != 0)
180 GElf_Shdr
*tshdr
= gelf_getshdr (section
, &shdr
);
182 assert (tshdr
== &shdr
);
183 t
= elf_strptr (elf
, header
.e_shstrndx
, shdr
.sh_name
);
185 if (strcmp (t
, name
) == 0)
191 /* Returns the IL symbol table of file ELF. */
194 get_symtab (Elf
*elf
)
197 Elf_Scn
*section
= get_section (elf
, ".gnu.lto_.symtab");
201 data
= elf_getdata (section
, data
);
206 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
209 translate (Elf_Data
*symtab
, struct plugin_symtab
*out
)
211 uint32_t *slots
= NULL
;
212 char *data
= symtab
->d_buf
;
213 char *end
= data
+ symtab
->d_size
;
214 struct ld_plugin_symbol
*syms
= NULL
;
220 syms
= realloc (syms
, n
* sizeof (struct ld_plugin_symbol
));
222 slots
= realloc (slots
, n
* sizeof (uint32_t));
224 data
= parse_table_entry (data
, &syms
[n
- 1], &slots
[n
- 1]);
232 /* Free all memory that is no longer needed after writing the symbol
239 for (i
= 0; i
< num_claimed_files
; i
++)
241 struct plugin_file_info
*info
= &claimed_files
[i
];
242 struct plugin_symtab
*symtab
= &info
->symtab
;
244 for (j
= 0; j
< symtab
->nsyms
; j
++)
246 struct ld_plugin_symbol
*s
= &symtab
->syms
[j
];
249 free (s
->comdat_key
);
256 /* Free all remaining memory. */
262 for (i
= 0; i
< num_claimed_files
; i
++)
264 struct plugin_file_info
*info
= &claimed_files
[i
];
265 struct plugin_symtab
*symtab
= &info
->symtab
;
266 free (symtab
->slots
);
270 for (i
= 0; i
< num_output_files
; i
++)
271 free (output_files
[i
]);
274 free (claimed_files
);
275 claimed_files
= NULL
;
276 num_claimed_files
= 0;
278 free (temp_obj_dir_name
);
279 temp_obj_dir_name
= NULL
;
283 free (resolution_file
);
284 resolution_file
= NULL
;
288 /* Writes the relocations to disk. */
291 write_resolution (void)
296 if (!resolution_file
)
299 f
= fopen (resolution_file
, "w");
302 fprintf (f
, "%d\n", num_claimed_files
);
304 for (i
= 0; i
< num_claimed_files
; i
++)
306 struct plugin_file_info
*info
= &claimed_files
[i
];
307 struct plugin_symtab
*symtab
= &info
->symtab
;
308 struct ld_plugin_symbol
*syms
= symtab
->syms
;
312 get_symbols (info
->handle
, symtab
->nsyms
, syms
);
314 fprintf (f
, "%s %d\n", info
->name
, info
->symtab
.nsyms
);
316 for (j
= 0; j
< info
->symtab
.nsyms
; j
++)
318 uint32_t slot
= symtab
->slots
[j
];
319 unsigned int resolution
= syms
[j
].resolution
;
320 fprintf (f
, "%d %s\n", slot
, lto_resolution_str
[resolution
]);
326 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
330 add_output_files (FILE *f
)
332 char fname
[1000]; /* FIXME: Is this big enough? */
337 char *s
= fgets (fname
, sizeof (fname
), f
);
342 assert (s
[len
- 1] == '\n');
346 output_files
= realloc (output_files
, num_output_files
* sizeof (char *));
347 output_files
[num_output_files
- 1] = strdup (s
);
348 add_input_file (output_files
[num_output_files
- 1]);
352 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
356 exec_lto_wrapper (char *argv
[])
363 FILE *wrapper_output
;
368 /* Write argv to a file to avoid a command line that is too long. */
369 t
= asprintf (&at_args
, "@%s/arguments", temp_obj_dir_name
);
372 args_name
= at_args
+ 1;
373 args
= fopen (args_name
, "w");
376 t
= writeargv (&argv
[1], args
);
381 new_argv
[0] = argv
[0];
382 new_argv
[1] = at_args
;
388 for (i
= 0; new_argv
[i
]; i
++)
389 fprintf (stderr
, "%s ", new_argv
[i
]);
390 fprintf (stderr
, "\n");
394 pex
= pex_init (PEX_USE_PIPES
, "lto-wrapper", NULL
);
395 assert (pex
!= NULL
);
397 errmsg
= pex_run (pex
, 0, new_argv
[0], new_argv
, NULL
, NULL
, &t
);
398 assert (errmsg
== NULL
);
401 wrapper_output
= pex_read_output (pex
, 0);
402 assert (wrapper_output
);
404 add_output_files (wrapper_output
);
406 t
= pex_get_status (pex
, 1, &status
);
408 assert (WIFEXITED (status
) && WEXITSTATUS (status
) == 0);
412 t
= unlink (args_name
);
417 /* Pass the original files back to the linker. */
420 use_original_files (void)
423 for (i
= 0; i
< num_claimed_files
; i
++)
425 struct plugin_file_info
*info
= &claimed_files
[i
];
426 add_input_file (info
->name
);
431 /* Called by the linker once all symbols have been read. */
433 static enum ld_plugin_status
434 all_symbols_read_handler (void)
437 unsigned num_lto_args
= num_claimed_files
+ lto_wrapper_num_args
+ 1;
439 const char **lto_arg_ptr
;
440 if (num_claimed_files
== 0)
445 use_original_files ();
449 lto_argv
= (char **) calloc (sizeof (char *), num_lto_args
);
450 lto_arg_ptr
= (const char **) lto_argv
;
451 assert (lto_wrapper_argv
);
457 for (i
= 0; i
< lto_wrapper_num_args
; i
++)
458 *lto_arg_ptr
++ = lto_wrapper_argv
[i
];
460 for (i
= 0; i
< num_claimed_files
; i
++)
462 struct plugin_file_info
*info
= &claimed_files
[i
];
464 *lto_arg_ptr
++ = info
->name
;
467 *lto_arg_ptr
++ = NULL
;
468 exec_lto_wrapper (lto_argv
);
472 if (pass_through_items
)
475 for (i
= 0; i
< num_pass_through_items
; i
++)
477 if (strncmp (pass_through_items
[i
], "-l", 2) == 0)
478 add_input_library (pass_through_items
[i
] + 2);
480 add_input_file (pass_through_items
[i
]);
481 free (pass_through_items
[i
]);
482 pass_through_items
[i
] = NULL
;
484 free (pass_through_items
);
485 pass_through_items
= NULL
;
491 /* Remove temporary files at the end of the link. */
493 static enum ld_plugin_status
494 cleanup_handler (void)
499 for (i
= 0; i
< num_claimed_files
; i
++)
501 struct plugin_file_info
*info
= &claimed_files
[i
];
504 t
= unlink (info
->name
);
508 t
= rmdir (temp_obj_dir_name
);
515 /* Callback used by gold to check if the plugin will claim FILE. Writes
516 the result in CLAIMED. */
518 static enum ld_plugin_status
519 claim_file_handler (const struct ld_plugin_input_file
*file
, int *claimed
)
521 enum ld_plugin_status status
;
523 struct plugin_file_info lto_file
;
527 if (file
->offset
!= 0)
529 /* FIXME lto: lto1 should know how to handle archives. */
531 off_t size
= file
->filesize
;
534 static int objnum
= 0;
536 int t
= asprintf (&objname
, "%s/obj%d.o",
537 temp_obj_dir_name
, objnum
);
541 fd
= open (objname
, O_RDWR
| O_CREAT
, 0666);
543 offset
= lseek (file
->fd
, file
->offset
, SEEK_SET
);
544 assert (offset
== file
->offset
);
549 off_t s
= sizeof (buf
) < size
? sizeof (buf
) : size
;
550 r
= read (file
->fd
, buf
, s
);
551 written
= write (fd
, buf
, r
);
552 assert (written
= r
);
555 lto_file
.name
= objname
;
557 lto_file
.handle
= file
->handle
;
562 lto_file
.name
= strdup (file
->name
);
563 lto_file_fd
= file
->fd
;
564 lto_file
.handle
= file
->handle
;
567 elf
= elf_begin (lto_file_fd
, ELF_C_READ
, NULL
);
574 symtab
= get_symtab (elf
);
578 translate (symtab
, <o_file
.symtab
);
580 status
= add_symbols (file
->handle
, lto_file
.symtab
.nsyms
,
581 lto_file
.symtab
.syms
);
582 assert (status
== LDPS_OK
);
587 realloc (claimed_files
,
588 num_claimed_files
* sizeof (struct plugin_file_info
));
589 claimed_files
[num_claimed_files
- 1] = lto_file
;
594 if (file
->offset
!= 0)
596 int t
= unlink (lto_file
.name
);
599 free (lto_file
.name
);
608 /* Parse the plugin options. */
611 process_option (const char *option
)
613 if (strcmp (option
, "-debug") == 0)
615 else if (strcmp (option
, "-nop") == 0)
617 else if (!strncmp (option
, "-resolution=", strlen("-resolution=")))
619 resolution_file
= strdup (option
+ strlen("-resolution="));
621 else if (!strncmp (option
, "-pass-through=", strlen("-pass-through=")))
623 num_pass_through_items
++;
624 pass_through_items
= realloc (pass_through_items
,
625 num_pass_through_items
* sizeof (char *));
626 pass_through_items
[num_pass_through_items
- 1] =
627 strdup (option
+ strlen ("-pass-through="));
632 lto_wrapper_num_args
+= 1;
633 size
= lto_wrapper_num_args
* sizeof (char *);
634 lto_wrapper_argv
= (char **) realloc (lto_wrapper_argv
, size
);
635 lto_wrapper_argv
[lto_wrapper_num_args
- 1] = strdup(option
);
639 /* Called by gold after loading the plugin. TV is the transfer vector. */
641 enum ld_plugin_status
642 onload (struct ld_plugin_tv
*tv
)
644 struct ld_plugin_tv
*p
;
645 enum ld_plugin_status status
;
648 unsigned version
= elf_version (EV_CURRENT
);
649 assert (version
!= EV_NONE
);
656 case LDPT_REGISTER_CLAIM_FILE_HOOK
:
657 register_claim_file
= p
->tv_u
.tv_register_claim_file
;
659 case LDPT_ADD_SYMBOLS
:
660 add_symbols
= p
->tv_u
.tv_add_symbols
;
662 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
:
663 register_all_symbols_read
= p
->tv_u
.tv_register_all_symbols_read
;
665 case LDPT_GET_SYMBOLS
:
666 get_symbols
= p
->tv_u
.tv_get_symbols
;
668 case LDPT_REGISTER_CLEANUP_HOOK
:
669 register_cleanup
= p
->tv_u
.tv_register_cleanup
;
671 case LDPT_ADD_INPUT_FILE
:
672 add_input_file
= p
->tv_u
.tv_add_input_file
;
674 case LDPT_ADD_INPUT_LIBRARY
:
675 add_input_library
= p
->tv_u
.tv_add_input_library
;
678 process_option (p
->tv_u
.tv_string
);
686 assert (register_claim_file
);
687 assert (add_symbols
);
688 status
= register_claim_file (claim_file_handler
);
689 assert (status
== LDPS_OK
);
691 if (register_cleanup
)
693 status
= register_cleanup (cleanup_handler
);
694 assert (status
== LDPS_OK
);
697 if (register_all_symbols_read
)
699 assert (get_symbols
);
700 status
= register_all_symbols_read (all_symbols_read_handler
);
701 assert (status
== LDPS_OK
);
704 temp_obj_dir_name
= strdup ("tmp_objectsXXXXXX");
705 t
= mkdtemp (temp_obj_dir_name
);
706 assert (t
== temp_obj_dir_name
);