GCC LTO
f1.c
f2.c
test.c
f1.o
f2.o
test.o
compile&
assemble
compile&
assemble
compile&
assemble
linker test
gcc -flto -c f1.c
gcc -flto -c f2.c
gcc -flto -c test.c
gcc -flto f1.o f2.o test.o -o test
f1.c
f2.c
test.c
LGEN
LGEN
LGEN
f1.o
f2.o
test.o
WPA
test.ltrans0.o
test.ltrans1.o
cc1 -flto -c f1.c
cc1 -flto -c f2.c
cc1 -flto -c test.c
lto1 -fwpa -fltrans-output-list=test.out 
f1.o f2.o test.o
test.out:
test.ltrans0.o
test.ltrans1.o
LTO objects
test.ltrans0.o
test.ltrans1.o
LTRANS
LTRANS
test.ltrans0.l
trans.o
test.ltrans1.l
trans.o
ld test
lto1 -fltrans test.ltrans0.o -o test.ltrans0.s
lto1 -fltrans test.ltrans1.o -o test.ltrans1.s
as test.ltrans0.s -o test.ltrans0.ltrans.o
as test.ltrans1.s -o test.ltrans1.ltrans.o
target objects
$ gcc -v --save-temps f1.o f2.o test.o -O3 -flto -o test
/home/users/kai/gcc-x86/libexec/gcc/x86_64-pc-linux-gnu/6.4.1/collect2 -
plugin /home/users/kai/gcc-x86/libexec/gcc/x86_64-pc-linux-gnu/6.4.1/
liblto_plugin.so -plugin-opt=/home/users/kai/gcc-x86/libexec/gcc/x86_64-pc-
linux-gnu/6.4.1/lto-wrapper -plugin-opt=-fresolution=test.res …
liblto_plugin.so
• Linker will pass transfer vector by onload() in
liblto_plugin.so provided by GCC.
struct ld_plugin_tv {
enum ld_plugin_tag tv_tag;
union {
int tv_val;
const char *tv_string;
ld_plugin_register_claim_file tv_register_claim_file;
…

} tv_u;
};
tv_tag tv_u used by
LDPT_MESSAGE message O
LDPT_API_VERSION 1
LDPT_GNU_LD_VERSION major * 100 + minor
LDPT_LINKER_OUTPUT LDPO_REL / LDPO_EXEC / LDPO_PIE / LDPO_DYN
LDPT_OUTPUT_NAME output_filename
LDPT_REGISTER_CLAIM_FILE_HOOK register_claim_file (claim_file_handler) LD O
LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK register_all_symbols_read (all_symbols_read_handler) LD O
LDPT_REGISTER_CLEANUP_HOOK register_cleanup (cleanup_handler) LD O
LDPT_ADD_SYMBOLS add_symbols GCC O
LDPT_GET_INPUT_FILE get_input_file GCC
LDPT_GET_VIEW get_view GCC
LDPT_RELEASE_INPUT_FILE release_input_file GCC
LDPT_GET_SYMBOLS get_symbols_v1 GCC O
LDPT_GET_SYMBOLS_V2 get_symbols_v2 GCC O
LDPT_ADD_INPUT_FILE add_input_file GCC O
LDPT_ADD_INPUT_LIBRARY add_input_library GCC O
LDPT_SET_EXTRA_LIBRARY_PATH set_extra_library_path GCC
LDPT_OPTION $PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/5.4.1/lto-wrapper
LDPT_OPTION -fresolution=/tmp/ccCVtp8y.res
LDPT_NULL 0
Transfer Vector
claim_file_handler
• called by open_input_bfds () in linker
• process .gnu.lto_.symtab
• call add_symbols
open_input_bfds
claim_file_handler
(extract .gnu.lto_.symtab)
add_symbols
(add symbols to bfd symtab)
all_symbols_read_handler
• called after all symbols read in linker
• write_resolution ()
• get_symbols_v2: get symbol resolution information
• print to the resolution file
• prepare lto arguments
• lto-wrapper -fresolution=test.res -flinker-output=exec f1.o f2.o
test.o
• execute lto-wrapper
• call add_input_file () to add generated target objects.
cleanup_handler
• remove argument files.
• remove generated target objects after LTRANS
lto-wrapper
f1.o
f2.o
test.o
WPA
test.ltrans0.o
test.ltrans1.o
LTO objects
LTRANS
LTRANS
test.ltrans0.l
trans.o
test.ltrans1.l
trans.o
target objects
lto-wrapper
• process options in COLLECT_GCC_OPTIONS
• options given by command line
• decoded_options
• process options, .gnu.lto_.opts, in LTO objects
• options stored in LTO objects (.gnu.lto_.opts)
• merge_and_complain ()
• fdecoded_options
• fork gcc -xlto -c $fdecoded_options $decoded_options -fwpa …
• fork gcc -xlto -c $fdecoded_options $decoded_options -fltrans …
• print output_names to stdout
• GCC will read in output_names and pass to Linker to continue linking process.
Linker liblto_plugin.so lto-wrapper GCC
all_symbols_read_handler
gcc -fwpa
gcc -fltrans
print output_names
add_input_file
exec lto-wrapper

GCC LTO

  • 1.
  • 2.
    f1.c f2.c test.c f1.o f2.o test.o compile& assemble compile& assemble compile& assemble linker test gcc -flto-c f1.c gcc -flto -c f2.c gcc -flto -c test.c gcc -flto f1.o f2.o test.o -o test
  • 3.
    f1.c f2.c test.c LGEN LGEN LGEN f1.o f2.o test.o WPA test.ltrans0.o test.ltrans1.o cc1 -flto -cf1.c cc1 -flto -c f2.c cc1 -flto -c test.c lto1 -fwpa -fltrans-output-list=test.out f1.o f2.o test.o test.out: test.ltrans0.o test.ltrans1.o LTO objects
  • 4.
    test.ltrans0.o test.ltrans1.o LTRANS LTRANS test.ltrans0.l trans.o test.ltrans1.l trans.o ld test lto1 -fltranstest.ltrans0.o -o test.ltrans0.s lto1 -fltrans test.ltrans1.o -o test.ltrans1.s as test.ltrans0.s -o test.ltrans0.ltrans.o as test.ltrans1.s -o test.ltrans1.ltrans.o target objects
  • 5.
    $ gcc -v--save-temps f1.o f2.o test.o -O3 -flto -o test /home/users/kai/gcc-x86/libexec/gcc/x86_64-pc-linux-gnu/6.4.1/collect2 - plugin /home/users/kai/gcc-x86/libexec/gcc/x86_64-pc-linux-gnu/6.4.1/ liblto_plugin.so -plugin-opt=/home/users/kai/gcc-x86/libexec/gcc/x86_64-pc- linux-gnu/6.4.1/lto-wrapper -plugin-opt=-fresolution=test.res …
  • 6.
    liblto_plugin.so • Linker willpass transfer vector by onload() in liblto_plugin.so provided by GCC. struct ld_plugin_tv { enum ld_plugin_tag tv_tag; union { int tv_val; const char *tv_string; ld_plugin_register_claim_file tv_register_claim_file; …
 } tv_u; };
  • 7.
    tv_tag tv_u usedby LDPT_MESSAGE message O LDPT_API_VERSION 1 LDPT_GNU_LD_VERSION major * 100 + minor LDPT_LINKER_OUTPUT LDPO_REL / LDPO_EXEC / LDPO_PIE / LDPO_DYN LDPT_OUTPUT_NAME output_filename LDPT_REGISTER_CLAIM_FILE_HOOK register_claim_file (claim_file_handler) LD O LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK register_all_symbols_read (all_symbols_read_handler) LD O LDPT_REGISTER_CLEANUP_HOOK register_cleanup (cleanup_handler) LD O LDPT_ADD_SYMBOLS add_symbols GCC O LDPT_GET_INPUT_FILE get_input_file GCC LDPT_GET_VIEW get_view GCC LDPT_RELEASE_INPUT_FILE release_input_file GCC LDPT_GET_SYMBOLS get_symbols_v1 GCC O LDPT_GET_SYMBOLS_V2 get_symbols_v2 GCC O LDPT_ADD_INPUT_FILE add_input_file GCC O LDPT_ADD_INPUT_LIBRARY add_input_library GCC O LDPT_SET_EXTRA_LIBRARY_PATH set_extra_library_path GCC LDPT_OPTION $PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/5.4.1/lto-wrapper LDPT_OPTION -fresolution=/tmp/ccCVtp8y.res LDPT_NULL 0 Transfer Vector
  • 8.
    claim_file_handler • called byopen_input_bfds () in linker • process .gnu.lto_.symtab • call add_symbols open_input_bfds claim_file_handler (extract .gnu.lto_.symtab) add_symbols (add symbols to bfd symtab)
  • 9.
    all_symbols_read_handler • called afterall symbols read in linker • write_resolution () • get_symbols_v2: get symbol resolution information • print to the resolution file • prepare lto arguments • lto-wrapper -fresolution=test.res -flinker-output=exec f1.o f2.o test.o • execute lto-wrapper • call add_input_file () to add generated target objects.
  • 10.
    cleanup_handler • remove argumentfiles. • remove generated target objects after LTRANS
  • 11.
  • 12.
    lto-wrapper • process optionsin COLLECT_GCC_OPTIONS • options given by command line • decoded_options • process options, .gnu.lto_.opts, in LTO objects • options stored in LTO objects (.gnu.lto_.opts) • merge_and_complain () • fdecoded_options • fork gcc -xlto -c $fdecoded_options $decoded_options -fwpa … • fork gcc -xlto -c $fdecoded_options $decoded_options -fltrans … • print output_names to stdout • GCC will read in output_names and pass to Linker to continue linking process.
  • 13.
    Linker liblto_plugin.so lto-wrapperGCC all_symbols_read_handler gcc -fwpa gcc -fltrans print output_names add_input_file exec lto-wrapper