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
;
101 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
102 by P and the result is written in ENTRY. The slot number is stored in SLOT.
103 Returns the address of the next entry. */
106 parse_table_entry (char *p
, struct ld_plugin_symbol
*entry
, uint32_t *slot
)
109 enum ld_plugin_symbol_kind translate_kind
[] =
118 enum ld_plugin_symbol_visibility translate_visibility
[] =
126 entry
->name
= strdup (p
);
131 entry
->version
= NULL
;
133 entry
->comdat_key
= p
;
138 if (strlen (entry
->comdat_key
) == 0)
139 entry
->comdat_key
= NULL
;
141 entry
->comdat_key
= strdup (entry
->comdat_key
);
145 entry
->def
= translate_kind
[t
];
150 entry
->visibility
= translate_visibility
[t
];
153 entry
->size
= *(uint64_t *) p
;
156 *slot
= *(uint32_t *) p
;
159 entry
->resolution
= LDPR_UNKNOWN
;
164 /* Return the section in ELF that is named NAME. */
167 get_section (Elf
*elf
, const char *name
)
169 Elf_Scn
*section
= 0;
171 GElf_Ehdr
*t
= gelf_getehdr (elf
, &header
);
174 assert (t
== &header
);
176 while ((section
= elf_nextscn(elf
, section
)) != 0)
179 GElf_Shdr
*tshdr
= gelf_getshdr (section
, &shdr
);
181 assert (tshdr
== &shdr
);
182 t
= elf_strptr (elf
, header
.e_shstrndx
, shdr
.sh_name
);
184 if (strcmp (t
, name
) == 0)
190 /* Returns the IL symbol table of file ELF. */
193 get_symtab (Elf
*elf
)
196 Elf_Scn
*section
= get_section (elf
, ".gnu.lto_.symtab");
200 data
= elf_getdata (section
, data
);
205 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
208 translate (Elf_Data
*symtab
, struct plugin_symtab
*out
)
210 uint32_t *slots
= NULL
;
211 char *data
= symtab
->d_buf
;
212 char *end
= data
+ symtab
->d_size
;
213 struct ld_plugin_symbol
*syms
= NULL
;
219 syms
= realloc (syms
, n
* sizeof (struct ld_plugin_symbol
));
221 slots
= realloc (slots
, n
* sizeof (uint32_t));
223 data
= parse_table_entry (data
, &syms
[n
- 1], &slots
[n
- 1]);
231 /* Free all memory that is no longer needed at the beginning of all_symbols_read. */
237 for (i
= 0; i
< num_claimed_files
; i
++)
239 struct plugin_file_info
*info
= &claimed_files
[i
];
240 struct plugin_symtab
*symtab
= &info
->symtab
;
242 for (j
= 0; j
< symtab
->nsyms
; j
++)
244 struct ld_plugin_symbol
*s
= &symtab
->syms
[j
];
247 free (s
->comdat_key
);
254 /* Free all remaining memory. */
260 for (i
= 0; i
< num_claimed_files
; i
++)
262 struct plugin_file_info
*info
= &claimed_files
[i
];
263 struct plugin_symtab
*symtab
= &info
->symtab
;
264 free (symtab
->slots
);
268 for (i
= 0; i
< num_output_files
; i
++)
269 free (output_files
[i
]);
272 free (claimed_files
);
273 claimed_files
= NULL
;
274 num_claimed_files
= 0;
276 free (temp_obj_dir_name
);
277 temp_obj_dir_name
= NULL
;
280 /* Writes the relocations to disk. */
283 write_resolution (void)
287 /* FIXME: Disabled for now since we are not using the resolution file. */
291 /* FIXME: This should be a temporary file. */
292 f
= fopen ("resolution", "w");
294 fprintf (f
, "%d\n", num_claimed_files
);
296 for (i
= 0; i
< num_claimed_files
; i
++)
298 struct plugin_file_info
*info
= &claimed_files
[i
];
299 struct plugin_symtab
*symtab
= &info
->symtab
;
300 struct ld_plugin_symbol
*syms
= calloc (symtab
->nsyms
,
301 sizeof (struct ld_plugin_symbol
));
305 get_symbols (info
->handle
, symtab
->nsyms
, syms
);
307 fprintf (f
, "%s %d\n", info
->name
, info
->symtab
.nsyms
);
309 for (j
= 0; j
< info
->symtab
.nsyms
; j
++)
311 uint32_t slot
= symtab
->slots
[j
];
312 unsigned int resolution
= syms
[j
].resolution
;
313 fprintf (f
, "%d %s\n", slot
, lto_resolution_str
[resolution
]);
320 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
324 add_output_files (FILE *f
)
326 char fname
[1000]; /* FIXME: Is this big enough? */
331 char *s
= fgets (fname
, sizeof (fname
), f
);
336 assert (s
[len
- 1] == '\n');
340 output_files
= realloc (output_files
, num_output_files
* sizeof (char *));
341 output_files
[num_output_files
- 1] = strdup (s
);
342 add_input_file (output_files
[num_output_files
- 1]);
346 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
350 exec_lto_wrapper (char *argv
[])
357 FILE *wrapper_output
;
362 /* Write argv to a file to avoid a command line that is too long. */
363 t
= asprintf (&at_args
, "@%s/arguments", temp_obj_dir_name
);
366 args_name
= at_args
+ 1;
367 args
= fopen (args_name
, "w");
370 t
= writeargv (&argv
[1], args
);
375 new_argv
[0] = argv
[0];
376 new_argv
[1] = at_args
;
382 for (i
= 0; new_argv
[i
]; i
++)
383 fprintf (stderr
, "%s ", new_argv
[i
]);
384 fprintf (stderr
, "\n");
388 pex
= pex_init (PEX_USE_PIPES
, "lto-wrapper", NULL
);
389 assert (pex
!= NULL
);
391 errmsg
= pex_run (pex
, 0, new_argv
[0], new_argv
, NULL
, NULL
, &t
);
392 assert (errmsg
== NULL
);
395 wrapper_output
= pex_read_output (pex
, 0);
396 assert (wrapper_output
);
398 add_output_files (wrapper_output
);
400 t
= pex_get_status (pex
, 1, &status
);
402 assert (WIFEXITED (status
) && WEXITSTATUS (status
) == 0);
406 t
= unlink (args_name
);
411 /* Pass the original files back to the linker. */
414 use_original_files (void)
417 for (i
= 0; i
< num_claimed_files
; i
++)
419 struct plugin_file_info
*info
= &claimed_files
[i
];
420 add_input_file (info
->name
);
425 /* Called by the linker once all symbols have been read. */
427 static enum ld_plugin_status
428 all_symbols_read_handler (void)
431 unsigned num_lto_args
= num_claimed_files
+ lto_wrapper_num_args
+ 1;
433 const char **lto_arg_ptr
;
434 if (num_claimed_files
== 0)
441 use_original_files ();
445 lto_argv
= (char **) calloc (sizeof (char *), num_lto_args
);
446 lto_arg_ptr
= (const char **) lto_argv
;
447 assert (lto_wrapper_argv
);
451 for (i
= 0; i
< lto_wrapper_num_args
; i
++)
452 *lto_arg_ptr
++ = lto_wrapper_argv
[i
];
454 for (i
= 0; i
< num_claimed_files
; i
++)
456 struct plugin_file_info
*info
= &claimed_files
[i
];
458 *lto_arg_ptr
++ = info
->name
;
461 *lto_arg_ptr
++ = NULL
;
462 exec_lto_wrapper (lto_argv
);
466 if (pass_through_items
)
469 for (i
= 0; i
< num_pass_through_items
; i
++)
471 if (strncmp (pass_through_items
[i
], "-l", 2) == 0)
472 add_input_library (pass_through_items
[i
] + 2);
474 add_input_file (pass_through_items
[i
]);
475 free (pass_through_items
[i
]);
476 pass_through_items
[i
] = NULL
;
478 free (pass_through_items
);
479 pass_through_items
= NULL
;
485 /* Remove temporary files at the end of the link. */
487 static enum ld_plugin_status
488 cleanup_handler (void)
493 for (i
= 0; i
< num_claimed_files
; i
++)
495 struct plugin_file_info
*info
= &claimed_files
[i
];
498 t
= unlink (info
->name
);
502 t
= rmdir (temp_obj_dir_name
);
509 /* Callback used by gold to check if the plugin will claim FILE. Writes
510 the result in CLAIMED. */
512 static enum ld_plugin_status
513 claim_file_handler (const struct ld_plugin_input_file
*file
, int *claimed
)
515 enum ld_plugin_status status
;
517 struct plugin_file_info lto_file
;
521 if (file
->offset
!= 0)
523 /* FIXME lto: lto1 should know how to handle archives. */
525 off_t size
= file
->filesize
;
528 static int objnum
= 0;
530 int t
= asprintf (&objname
, "%s/obj%d.o",
531 temp_obj_dir_name
, objnum
);
535 fd
= open (objname
, O_RDWR
| O_CREAT
, 0666);
537 offset
= lseek (file
->fd
, file
->offset
, SEEK_SET
);
538 assert (offset
== file
->offset
);
543 off_t s
= sizeof (buf
) < size
? sizeof (buf
) : size
;
544 r
= read (file
->fd
, buf
, s
);
545 written
= write (fd
, buf
, r
);
546 assert (written
= r
);
549 lto_file
.name
= objname
;
551 lto_file
.handle
= file
->handle
;
556 lto_file
.name
= strdup (file
->name
);
557 lto_file_fd
= file
->fd
;
558 lto_file
.handle
= file
->handle
;
561 elf
= elf_begin (lto_file_fd
, ELF_C_READ
, NULL
);
568 symtab
= get_symtab (elf
);
572 translate (symtab
, <o_file
.symtab
);
574 status
= add_symbols (file
->handle
, lto_file
.symtab
.nsyms
,
575 lto_file
.symtab
.syms
);
576 assert (status
== LDPS_OK
);
581 realloc (claimed_files
,
582 num_claimed_files
* sizeof (struct plugin_file_info
));
583 claimed_files
[num_claimed_files
- 1] = lto_file
;
588 if (file
->offset
!= 0)
590 int t
= unlink (lto_file
.name
);
593 free (lto_file
.name
);
602 /* Parse the plugin options. */
605 process_option (const char *option
)
607 if (strcmp (option
, "-debug") == 0)
609 else if (strcmp (option
, "-nop") == 0)
611 else if (!strncmp (option
, "-pass-through=", strlen("-pass-through=")))
613 num_pass_through_items
++;
614 pass_through_items
= realloc (pass_through_items
,
615 num_pass_through_items
* sizeof (char *));
616 pass_through_items
[num_pass_through_items
- 1] =
617 strdup (option
+ strlen ("-pass-through="));
622 lto_wrapper_num_args
+= 1;
623 size
= lto_wrapper_num_args
* sizeof (char *);
624 lto_wrapper_argv
= (char **) realloc (lto_wrapper_argv
, size
);
625 lto_wrapper_argv
[lto_wrapper_num_args
- 1] = strdup(option
);
629 /* Called by gold after loading the plugin. TV is the transfer vector. */
631 enum ld_plugin_status
632 onload (struct ld_plugin_tv
*tv
)
634 struct ld_plugin_tv
*p
;
635 enum ld_plugin_status status
;
638 unsigned version
= elf_version (EV_CURRENT
);
639 assert (version
!= EV_NONE
);
646 case LDPT_REGISTER_CLAIM_FILE_HOOK
:
647 register_claim_file
= p
->tv_u
.tv_register_claim_file
;
649 case LDPT_ADD_SYMBOLS
:
650 add_symbols
= p
->tv_u
.tv_add_symbols
;
652 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
:
653 register_all_symbols_read
= p
->tv_u
.tv_register_all_symbols_read
;
655 case LDPT_GET_SYMBOLS
:
656 get_symbols
= p
->tv_u
.tv_get_symbols
;
658 case LDPT_REGISTER_CLEANUP_HOOK
:
659 register_cleanup
= p
->tv_u
.tv_register_cleanup
;
661 case LDPT_ADD_INPUT_FILE
:
662 add_input_file
= p
->tv_u
.tv_add_input_file
;
664 case LDPT_ADD_INPUT_LIBRARY
:
665 add_input_library
= p
->tv_u
.tv_add_input_library
;
668 process_option (p
->tv_u
.tv_string
);
676 assert (register_claim_file
);
677 assert (add_symbols
);
678 status
= register_claim_file (claim_file_handler
);
679 assert (status
== LDPS_OK
);
681 if (register_cleanup
)
683 status
= register_cleanup (cleanup_handler
);
684 assert (status
== LDPS_OK
);
687 if (register_all_symbols_read
)
689 assert (get_symbols
);
690 status
= register_all_symbols_read (all_symbols_read_handler
);
691 assert (status
== LDPS_OK
);
694 temp_obj_dir_name
= strdup ("tmp_objectsXXXXXX");
695 t
= mkdtemp (temp_obj_dir_name
);
696 assert (t
== temp_obj_dir_name
);