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
;
85 static struct plugin_file_info
*claimed_files
= NULL
;
86 static unsigned int num_claimed_files
= 0;
88 static char **output_files
= NULL
;
89 static unsigned int num_output_files
= 0;
91 static char **lto_wrapper_argv
;
92 static int lto_wrapper_num_args
;
94 static char **pass_through_items
= NULL
;
95 static unsigned int num_pass_through_items
;
100 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
101 by P and the result is written in ENTRY. The slot number is stored in SLOT.
102 Returns the address of the next entry. */
105 parse_table_entry (char *p
, struct ld_plugin_symbol
*entry
, uint32_t *slot
)
108 enum ld_plugin_symbol_kind translate_kind
[] =
117 enum ld_plugin_symbol_visibility translate_visibility
[] =
125 entry
->name
= strdup (p
);
130 entry
->version
= NULL
;
132 entry
->comdat_key
= p
;
137 if (strlen (entry
->comdat_key
) == 0)
138 entry
->comdat_key
= NULL
;
140 entry
->comdat_key
= strdup (entry
->comdat_key
);
144 entry
->def
= translate_kind
[t
];
149 entry
->visibility
= translate_visibility
[t
];
152 entry
->size
= *(uint64_t *) p
;
155 *slot
= *(uint32_t *) p
;
158 entry
->resolution
= LDPR_UNKNOWN
;
163 /* Return the section in ELF that is named NAME. */
166 get_section (Elf
*elf
, const char *name
)
168 Elf_Scn
*section
= 0;
170 GElf_Ehdr
*t
= gelf_getehdr (elf
, &header
);
173 assert (t
== &header
);
175 while ((section
= elf_nextscn(elf
, section
)) != 0)
178 GElf_Shdr
*tshdr
= gelf_getshdr (section
, &shdr
);
180 assert (tshdr
== &shdr
);
181 t
= elf_strptr (elf
, header
.e_shstrndx
, shdr
.sh_name
);
183 if (strcmp (t
, name
) == 0)
189 /* Returns the IL symbol table of file ELF. */
192 get_symtab (Elf
*elf
)
195 Elf_Scn
*section
= get_section (elf
, ".gnu.lto_.symtab");
199 data
= elf_getdata (section
, data
);
204 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
207 translate (Elf_Data
*symtab
, struct plugin_symtab
*out
)
209 uint32_t *slots
= NULL
;
210 char *data
= symtab
->d_buf
;
211 char *end
= data
+ symtab
->d_size
;
212 struct ld_plugin_symbol
*syms
= NULL
;
218 syms
= realloc (syms
, n
* sizeof (struct ld_plugin_symbol
));
220 slots
= realloc (slots
, n
* sizeof (uint32_t));
222 data
= parse_table_entry (data
, &syms
[n
- 1], &slots
[n
- 1]);
230 /* Free all memory that is no longer needed at the beginning of all_symbols_read. */
236 for (i
= 0; i
< num_claimed_files
; i
++)
238 struct plugin_file_info
*info
= &claimed_files
[i
];
239 struct plugin_symtab
*symtab
= &info
->symtab
;
241 for (j
= 0; j
< symtab
->nsyms
; j
++)
243 struct ld_plugin_symbol
*s
= &symtab
->syms
[j
];
246 free (s
->comdat_key
);
253 /* Free all remaining memory. */
259 for (i
= 0; i
< num_claimed_files
; i
++)
261 struct plugin_file_info
*info
= &claimed_files
[i
];
262 struct plugin_symtab
*symtab
= &info
->symtab
;
263 free (symtab
->slots
);
267 for (i
= 0; i
< num_output_files
; i
++)
268 free (output_files
[i
]);
271 free (claimed_files
);
272 claimed_files
= NULL
;
273 num_claimed_files
= 0;
275 free (temp_obj_dir_name
);
276 temp_obj_dir_name
= NULL
;
279 /* Writes the relocations to disk. */
282 write_resolution (void)
286 /* FIXME: Disabled for now since we are not using the resolution file. */
290 /* FIXME: This should be a temporary file. */
291 f
= fopen ("resolution", "w");
293 fprintf (f
, "%d\n", num_claimed_files
);
295 for (i
= 0; i
< num_claimed_files
; i
++)
297 struct plugin_file_info
*info
= &claimed_files
[i
];
298 struct plugin_symtab
*symtab
= &info
->symtab
;
299 struct ld_plugin_symbol
*syms
= calloc (symtab
->nsyms
,
300 sizeof (struct ld_plugin_symbol
));
304 get_symbols (info
->handle
, symtab
->nsyms
, syms
);
306 fprintf (f
, "%s %d\n", info
->name
, info
->symtab
.nsyms
);
308 for (j
= 0; j
< info
->symtab
.nsyms
; j
++)
310 uint32_t slot
= symtab
->slots
[j
];
311 unsigned int resolution
= syms
[j
].resolution
;
312 fprintf (f
, "%d %s\n", slot
, lto_resolution_str
[resolution
]);
319 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
323 add_output_files (FILE *f
)
325 char fname
[1000]; /* FIXME: Is this big enough? */
330 char *s
= fgets (fname
, sizeof (fname
), f
);
335 assert (s
[len
- 1] == '\n');
339 output_files
= realloc (output_files
, num_output_files
* sizeof (char *));
340 output_files
[num_output_files
- 1] = strdup (s
);
341 add_input_file (output_files
[num_output_files
- 1]);
345 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
349 exec_lto_wrapper (char *argv
[])
356 FILE *wrapper_output
;
361 /* Write argv to a file to avoid a command line that is too long. */
362 t
= asprintf (&at_args
, "@%s/arguments", temp_obj_dir_name
);
365 args_name
= at_args
+ 1;
366 args
= fopen (args_name
, "w");
369 t
= writeargv (&argv
[1], args
);
374 new_argv
[0] = argv
[0];
375 new_argv
[1] = at_args
;
381 for (i
= 0; new_argv
[i
]; i
++)
382 fprintf (stderr
, "%s ", new_argv
[i
]);
383 fprintf (stderr
, "\n");
387 pex
= pex_init (PEX_USE_PIPES
, "lto-wrapper", NULL
);
388 assert (pex
!= NULL
);
390 errmsg
= pex_run (pex
, 0, new_argv
[0], new_argv
, NULL
, NULL
, &t
);
391 assert (errmsg
== NULL
);
394 wrapper_output
= pex_read_output (pex
, 0);
395 assert (wrapper_output
);
397 add_output_files (wrapper_output
);
399 t
= pex_get_status (pex
, 1, &status
);
401 assert (WIFEXITED (status
) && WEXITSTATUS (status
) == 0);
405 t
= unlink (args_name
);
410 /* Pass the original files back to the linker. */
413 use_original_files (void)
416 for (i
= 0; i
< num_claimed_files
; i
++)
418 struct plugin_file_info
*info
= &claimed_files
[i
];
419 add_input_file (info
->name
);
424 /* Called by the linker once all symbols have been read. */
426 static enum ld_plugin_status
427 all_symbols_read_handler (void)
430 unsigned num_lto_args
= num_claimed_files
+ lto_wrapper_num_args
+ 1;
432 const char **lto_arg_ptr
;
433 if (num_claimed_files
== 0)
440 use_original_files ();
444 lto_argv
= (char **) calloc (sizeof (char *), num_lto_args
);
445 lto_arg_ptr
= (const char **) lto_argv
;
446 assert (lto_wrapper_argv
);
450 for (i
= 0; i
< lto_wrapper_num_args
; i
++)
451 *lto_arg_ptr
++ = lto_wrapper_argv
[i
];
453 for (i
= 0; i
< num_claimed_files
; i
++)
455 struct plugin_file_info
*info
= &claimed_files
[i
];
457 *lto_arg_ptr
++ = info
->name
;
460 *lto_arg_ptr
++ = NULL
;
461 exec_lto_wrapper (lto_argv
);
465 if (pass_through_items
)
468 for (i
= 0; i
< num_pass_through_items
; i
++)
470 add_input_file (pass_through_items
[i
]);
471 free (pass_through_items
[i
]);
472 pass_through_items
[i
] = NULL
;
474 free (pass_through_items
);
475 pass_through_items
= NULL
;
481 /* Remove temporary files at the end of the link. */
483 static enum ld_plugin_status
484 cleanup_handler (void)
489 for (i
= 0; i
< num_claimed_files
; i
++)
491 struct plugin_file_info
*info
= &claimed_files
[i
];
494 t
= unlink (info
->name
);
498 t
= rmdir (temp_obj_dir_name
);
505 /* Callback used by gold to check if the plugin will claim FILE. Writes
506 the result in CLAIMED. */
508 static enum ld_plugin_status
509 claim_file_handler (const struct ld_plugin_input_file
*file
, int *claimed
)
511 enum ld_plugin_status status
;
513 struct plugin_file_info lto_file
;
517 if (file
->offset
!= 0)
519 /* FIXME lto: lto1 should know how to handle archives. */
521 off_t size
= file
->filesize
;
524 static int objnum
= 0;
526 int t
= asprintf (&objname
, "%s/obj%d.o",
527 temp_obj_dir_name
, objnum
);
531 fd
= open (objname
, O_RDWR
| O_CREAT
, 0666);
533 offset
= lseek (file
->fd
, file
->offset
, SEEK_SET
);
534 assert (offset
== file
->offset
);
539 off_t s
= sizeof (buf
) < size
? sizeof (buf
) : size
;
540 r
= read (file
->fd
, buf
, s
);
541 written
= write (fd
, buf
, r
);
542 assert (written
= r
);
545 lto_file
.name
= objname
;
547 lto_file
.handle
= file
->handle
;
552 lto_file
.name
= strdup (file
->name
);
553 lto_file_fd
= file
->fd
;
554 lto_file
.handle
= file
->handle
;
557 elf
= elf_begin (lto_file_fd
, ELF_C_READ
, NULL
);
564 symtab
= get_symtab (elf
);
568 translate (symtab
, <o_file
.symtab
);
570 status
= add_symbols (file
->handle
, lto_file
.symtab
.nsyms
,
571 lto_file
.symtab
.syms
);
572 assert (status
== LDPS_OK
);
577 realloc (claimed_files
,
578 num_claimed_files
* sizeof (struct plugin_file_info
));
579 claimed_files
[num_claimed_files
- 1] = lto_file
;
584 if (file
->offset
!= 0)
586 int t
= unlink (lto_file
.name
);
589 free (lto_file
.name
);
598 /* Parse the plugin options. */
601 process_option (const char *option
)
603 if (strcmp (option
, "-debug") == 0)
605 else if (strcmp (option
, "-nop") == 0)
607 else if (!strncmp (option
, "-pass-through=", strlen("-pass-through=")))
609 num_pass_through_items
++;
610 pass_through_items
= realloc (pass_through_items
, num_pass_through_items
* sizeof (char *));
611 pass_through_items
[num_pass_through_items
- 1] = strdup (option
+ strlen ("-pass-through="));
616 lto_wrapper_num_args
+= 1;
617 size
= lto_wrapper_num_args
* sizeof (char *);
618 lto_wrapper_argv
= (char **) realloc (lto_wrapper_argv
, size
);
619 lto_wrapper_argv
[lto_wrapper_num_args
- 1] = strdup(option
);
623 /* Called by gold after loading the plugin. TV is the transfer vector. */
625 enum ld_plugin_status
626 onload (struct ld_plugin_tv
*tv
)
628 struct ld_plugin_tv
*p
;
629 enum ld_plugin_status status
;
632 unsigned version
= elf_version (EV_CURRENT
);
633 assert (version
!= EV_NONE
);
640 case LDPT_REGISTER_CLAIM_FILE_HOOK
:
641 register_claim_file
= p
->tv_u
.tv_register_claim_file
;
643 case LDPT_ADD_SYMBOLS
:
644 add_symbols
= p
->tv_u
.tv_add_symbols
;
646 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
:
647 register_all_symbols_read
= p
->tv_u
.tv_register_all_symbols_read
;
649 case LDPT_GET_SYMBOLS
:
650 get_symbols
= p
->tv_u
.tv_get_symbols
;
652 case LDPT_REGISTER_CLEANUP_HOOK
:
653 register_cleanup
= p
->tv_u
.tv_register_cleanup
;
655 case LDPT_ADD_INPUT_FILE
:
656 add_input_file
= p
->tv_u
.tv_add_input_file
;
659 process_option (p
->tv_u
.tv_string
);
667 assert (register_claim_file
);
668 assert (add_symbols
);
669 status
= register_claim_file (claim_file_handler
);
670 assert (status
== LDPS_OK
);
672 if (register_cleanup
)
674 status
= register_cleanup (cleanup_handler
);
675 assert (status
== LDPS_OK
);
678 if (register_all_symbols_read
)
680 assert (get_symbols
);
681 status
= register_all_symbols_read (all_symbols_read_handler
);
682 assert (status
== LDPS_OK
);
685 temp_obj_dir_name
= strdup ("tmp_objectsXXXXXX");
686 t
= mkdtemp (temp_obj_dir_name
);
687 assert (t
== temp_obj_dir_name
);