Bug 12088 - ar/nm plugin use requires GNUTARGET=plugin
Summary: ar/nm plugin use requires GNUTARGET=plugin
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-03 10:00 UTC by Andi Kleen
Modified: 2010-10-04 12:21 UTC (History)
2 users (show)

See Also:
Host: x86_64-linux
Target:
Build:
Last reconfirmed:


Attachments
test case demonstrating the ar problem (857 bytes, application/x-compressed-tar)
2010-10-04 07:02 UTC, Andi Kleen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andi Kleen 2010-10-03 10:00:43 UTC
% nm --plugin $(gcc46 -print-prog-name=liblto_plugin.so)  t.a

Doesn't print GCC LTO symbols, but

% GNUTARGET=plugin nm --plugin $(gcc46 -print-prog-name=liblto_plugin.so)  t.a

works.

Could the need for GNUTARGET be eliminated? It makes it more complicated
to use in Makefiles and will likely fail if some objects are not using
LTO.
Comment 1 H.J. Lu 2010-10-03 10:16:59 UTC
1. Please provide t.a for nm.
2. Please provide a testcase for ar.
Comment 2 Andi Kleen 2010-10-03 10:32:00 UTC
The LTO files are somewhat depending on the compiler version,
mine would not necessarily work with yours.

Just ar up a couple of LTO object files you have lying around for testing
(any .os compiled with with -flto or -fwhopr)

Just make sure to specify 's' so that the symbol table is generated.

The ar test case is the same as with nm

GNUTARGET=plugin ar --plugin ... qs 

vs

ar --plugin ... qs

Then check with nm  -s ... if the LTO symbols are in the archive symbol table

Comment 3 H.J. Lu 2010-10-03 10:34:39 UTC
Please show me that "ar --plugin" doesn't work. I
though I had fixed it in Sept.
Comment 4 cvs-commit@gcc.gnu.org 2010-10-03 10:49:36 UTC
Subject: Bug 12088

CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2010-10-03 10:49:20

Modified files:
	binutils       : ChangeLog nm.c 

Log message:
	Set BFD target to "plugin" for "nm --plugin".
	
	2010-10-03  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR binutils/12088
	* nm.c (plugin_target): New.
	(main): Set plugin_target to "plugin" for --plugin.
	(display_file): Pass plugin_target to bfd_openr if target
	isn't set.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/ChangeLog.diff?cvsroot=src&r1=1.1690&r2=1.1691
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/nm.c.diff?cvsroot=src&r1=1.63&r2=1.64

Comment 5 H.J. Lu 2010-10-03 10:52:20 UTC
Fixed.
Comment 6 Andi Kleen 2010-10-03 10:53:14 UTC
Sorry earlier recipe was not fully correct.

You also need to strip the non LTO data out of the objects before
aring them to reproduce the problem fully (otherwise it's unclear where the
symbols come from)

I do that with a little script http://halobates.de/ONLYLTO
Comment 7 Andi Kleen 2010-10-03 10:54:33 UTC
Thanks for the patch.

But does the patch work for the case when I pass some LTO and some non LTO
objects, but specify the plugin?  (that is does fallback to normal elf still work)
Comment 8 H.J. Lu 2010-10-03 10:57:54 UTC
(In reply to comment #7)
> But does the patch work for the case when I pass some LTO and some non LTO
> objects, but specify the plugin?  (that is does fallback to normal elf still work)

Please open a new bug if it doesn't work.
Comment 9 Andi Kleen 2010-10-03 18:53:08 UTC
The problem is still there for ar

Comment 10 H.J. Lu 2010-10-03 23:11:46 UTC
(In reply to comment #9)
> The problem is still there for ar
> 
> 

Works for me:

[hjl@gnu-6 pr12004]$ make
./ar --plugin
/export/build/gnu/gcc/release/usr/gcc-4.6.0/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/liblto_plugin.so.0.0.0
qs libfoo.a libiberty/alloca.o libiberty/argv.o libiberty/choose-temp.o
libiberty/concat.o libiberty/cp-demangle.o libiberty/cp-demint.o
libiberty/cplus-dem.o libiberty/crc32.o libiberty/dyn-string.o
libiberty/fdmatch.o libiberty/fibheap.o libiberty/filename_cmp.o
libiberty/getopt.o libiberty/getpwd.o libiberty/getruntime.o
libiberty/floatformat.o libiberty/fnmatch.o libiberty/fopen_unlocked.o
libiberty/getopt1.o libiberty/hashtab.o libiberty/hex.o libiberty/lbasename.o
libiberty/lrealpath.o libiberty/make-relative-prefix.o
libiberty/make-temp-file.o libiberty/md5.o libiberty/objalloc.o
libiberty/obstack.o libiberty/partition.o libiberty/pex-common.o
libiberty/pexecute.o libiberty/pex-one.o libiberty/pex-unix.o
libiberty/physmem.o libiberty/regex.o libiberty/safe-ctype.o libiberty/sha1.o
libiberty/sort.o libiberty/spaces.o libiberty/splay-tree.o libiberty/strerror.o
libiberty/strsignal.o libiberty/unlink-if-ordinary.o libiberty/xatexit.o
libiberty/xexit.o libiberty/xmalloc.o libiberty/xmemdup.o libiberty/xstrdup.o
libiberty/xstrerror.o libiberty/xstrndup.o
./ar: creating libfoo.a
[hjl@gnu-6 pr12004]$ nm -s libfoo.a

Archive index:
C_alloca in alloca.o
libiberty_len in alloca.o
libiberty_nptr in alloca.o
libiberty_optr in alloca.o
freeargv in argv.o
dupargv in argv.o
buildargv in argv.o
writeargv in argv.o
expandargv in argv.o
choose_temp_base in choose-temp.o
concat_length in concat.o
concat_copy in concat.o
concat_copy2 in concat.o
concat in concat.o
reconcat in concat.o
libiberty_concat_ptr in concat.o
cplus_demangle_fill_name in cp-demangle.o
cplus_demangle_fill_extended_operator in cp-demangle.o
cplus_demangle_fill_ctor in cp-demangle.o
cplus_demangle_fill_dtor in cp-demangle.o
cplus_demangle_type in cp-demangle.o
cplus_demangle_mangled_name in cp-demangle.o
cplus_demangle_print_callback in cp-demangle.o
cplus_demangle_print in cp-demangle.o
cplus_demangle_init_info in cp-demangle.o
cplus_demangle_v3 in cp-demangle.o
cplus_demangle_v3_callback in cp-demangle.o
java_demangle_v3 in cp-demangle.o
java_demangle_v3_callback in cp-demangle.o
is_gnu_v3_mangled_ctor in cp-demangle.o
is_gnu_v3_mangled_dtor in cp-demangle.o
cplus_demangle_builtin_types in cp-demangle.o
cplus_demangle_operators in cp-demangle.o
cplus_demangle_fill_component in cp-demint.o
cplus_demangle_fill_builtin_type in cp-demint.o
cplus_demangle_fill_operator in cp-demint.o
cplus_demangle_v3_components in cp-demint.o
set_cplus_marker_for_demangling in cplus-dem.o
cplus_mangle_opname in cplus-dem.o
cplus_demangle_set_style in cplus-dem.o
cplus_demangle_name_to_style in cplus-dem.o
ada_demangle in cplus-dem.o
cplus_demangle in cplus-dem.o
cplus_demangle_opname in cplus-dem.o
current_demangling_style in cplus-dem.o
libiberty_demanglers in cplus-dem.o
xcrc32 in crc32.o
dyn_string_init in dyn-string.o
dyn_string_new in dyn-string.o
dyn_string_delete in dyn-string.o
dyn_string_release in dyn-string.o
dyn_string_resize in dyn-string.o
dyn_string_clear in dyn-string.o
dyn_string_copy in dyn-string.o
dyn_string_copy_cstr in dyn-string.o
dyn_string_insert in dyn-string.o
dyn_string_prepend in dyn-string.o
dyn_string_insert_cstr in dyn-string.o
dyn_string_prepend_cstr in dyn-string.o
dyn_string_insert_char in dyn-string.o
dyn_string_append in dyn-string.o
dyn_string_append_cstr in dyn-string.o
dyn_string_append_char in dyn-string.o
dyn_string_substring in dyn-string.o
dyn_string_eq in dyn-string.o
fdmatch in fdmatch.o
fibheap_new in fibheap.o
fibheap_insert in fibheap.o
fibheap_min in fibheap.o
fibheap_min_key in fibheap.o
fibheap_union in fibheap.o
fibheap_extract_min in fibheap.o
fibheap_replace_key_data in fibheap.o
fibheap_replace_data in fibheap.o
fibheap_replace_key in fibheap.o
fibheap_delete_node in fibheap.o
fibheap_delete in fibheap.o
fibheap_empty in fibheap.o
filename_cmp in filename_cmp.o
getpwd in getpwd.o
get_run_time in getruntime.o
floatformat_to_double in floatformat.o
floatformat_from_double in floatformat.o
floatformat_is_valid in floatformat.o
floatformat_ibm_long_double in floatformat.o
floatformat_ieee_double_big in floatformat.o
floatformat_ia64_quad_little in floatformat.o
floatformat_ia64_quad_big in floatformat.o
floatformat_ia64_spill_little in floatformat.o
floatformat_ia64_spill_big in floatformat.o
floatformat_arm_ext_littlebyte_bigword in floatformat.o
floatformat_arm_ext_big in floatformat.o
floatformat_m88110_harris_ext in floatformat.o
floatformat_m88110_ext in floatformat.o
floatformat_i960_ext in floatformat.o
floatformat_m68881_ext in floatformat.o
floatformat_i387_ext in floatformat.o
floatformat_vax_g in floatformat.o
floatformat_vax_d in floatformat.o
floatformat_vax_f in floatformat.o
floatformat_ieee_double_littlebyte_bigword in floatformat.o
floatformat_ieee_double_little in floatformat.o
floatformat_ieee_single_little in floatformat.o
floatformat_ieee_single_big in floatformat.o
floatformat_ieee_half_little in floatformat.o
floatformat_ieee_half_big in floatformat.o
unlock_stream in fopen_unlocked.o
unlock_std_streams in fopen_unlocked.o
fopen_unlocked in fopen_unlocked.o
fdopen_unlocked in fopen_unlocked.o
freopen_unlocked in fopen_unlocked.o
htab_size in hashtab.o
htab_elements in hashtab.o
htab_create_alloc_ex in hashtab.o
htab_create_typed_alloc in hashtab.o
htab_create_alloc in hashtab.o
htab_set_functions_ex in hashtab.o
htab_create in hashtab.o
htab_try_create in hashtab.o
htab_delete in hashtab.o
htab_empty in hashtab.o
htab_find_with_hash in hashtab.o
htab_find in hashtab.o
htab_find_slot_with_hash in hashtab.o
htab_find_slot in hashtab.o
htab_remove_elt_with_hash in hashtab.o
htab_remove_elt in hashtab.o
htab_clear_slot in hashtab.o
htab_traverse_noresize in hashtab.o
htab_traverse in hashtab.o
htab_collisions in hashtab.o
htab_hash_string in hashtab.o
iterative_hash in hashtab.o
htab_eq_pointer in hashtab.o
htab_hash_pointer in hashtab.o
hex_init in hex.o
_hex_value in hex.o
unix_lbasename in lbasename.o
dos_lbasename in lbasename.o
lbasename in lbasename.o
lrealpath in lrealpath.o
make_relative_prefix in make-relative-prefix.o
make_relative_prefix_ignore_links in make-relative-prefix.o
choose_tmpdir in make-temp-file.o
make_temp_file in make-temp-file.o
md5_init_ctx in md5.o
md5_read_ctx in md5.o
md5_process_block in md5.o
md5_process_bytes in md5.o
md5_finish_ctx in md5.o
md5_buffer in md5.o
md5_stream in md5.o
objalloc_create in objalloc.o
_objalloc_alloc in objalloc.o
objalloc_free in objalloc.o
objalloc_free_block in objalloc.o
partition_new in partition.o
partition_delete in partition.o
partition_union in partition.o
partition_print in partition.o
pex_init_common in pex-common.o
pex_run_in_environment in pex-common.o
pex_run in pex-common.o
pex_input_file in pex-common.o
pex_input_pipe in pex-common.o
pex_read_output in pex-common.o
pex_read_err in pex-common.o
pex_get_status in pex-common.o
pex_get_times in pex-common.o
pex_free in pex-common.o
pexecute in pexecute.o
pwait in pexecute.o
pex_one in pex-one.o
pex_init in pex-unix.o
funcs in pex-unix.o
physmem_total in physmem.o
physmem_available in physmem.o
xre_set_syntax in regex.o
xre_compile_fastmap in regex.o
xre_set_registers in regex.o
xre_search in regex.o
xre_search_2 in regex.o
xre_match in regex.o
xre_match_2 in regex.o
xre_compile_pattern in regex.o
xre_comp in regex.o
xre_exec in regex.o
xregcomp in regex.o
xregexec in regex.o
xregerror in regex.o
xregfree in regex.o
xre_max_failures in regex.o
xre_syntax_options in regex.o
_sch_toupper in safe-ctype.o
_sch_tolower in safe-ctype.o
_sch_istable in safe-ctype.o
sha1_init_ctx in sha1.o
sha1_read_ctx in sha1.o
sha1_process_block in sha1.o
sha1_process_bytes in sha1.o
sha1_finish_ctx in sha1.o
sha1_buffer in sha1.o
sha1_stream in sha1.o
sort_pointers in sort.o
spaces in spaces.o
splay_tree_new in splay-tree.o
splay_tree_new_with_allocator in splay-tree.o
splay_tree_new_typed_alloc in splay-tree.o
splay_tree_delete in splay-tree.o
splay_tree_insert in splay-tree.o
splay_tree_remove in splay-tree.o
splay_tree_lookup in splay-tree.o
splay_tree_max in splay-tree.o
splay_tree_min in splay-tree.o
splay_tree_predecessor in splay-tree.o
splay_tree_successor in splay-tree.o
splay_tree_foreach in splay-tree.o
splay_tree_compare_ints in splay-tree.o
splay_tree_compare_pointers in splay-tree.o
errno_max in strerror.o
strerrno in strerror.o
strtoerrno in strerror.o
signo_max in strsignal.o
strsigno in strsignal.o
strtosigno in strsignal.o
unlink_if_ordinary in unlink-if-ordinary.o
xatexit in xatexit.o
xexit in xexit.o
_xexit_cleanup in xexit.o
xmalloc_set_program_name in xmalloc.o
xmalloc_failed in xmalloc.o
xmalloc in xmalloc.o
xcalloc in xmalloc.o
xrealloc in xmalloc.o
xmemdup in xmemdup.o
xstrdup in xstrdup.o
xstrerror in xstrerror.o
xstrndup in xstrndup.o

alloca.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 b last_alloca_header
0000000000000008 C libiberty_len
0000000000000008 C libiberty_nptr
0000000000000008 C libiberty_optr

argv.o:
0000000000000001 C __gnu_lto_v1

choose-temp.o:
0000000000000001 C __gnu_lto_v1

concat.o:
0000000000000001 C __gnu_lto_v1
0000000000000008 C libiberty_concat_ptr

cp-demangle.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 R cplus_demangle_builtin_types
0000000000000420 R cplus_demangle_operators
0000000000000920 r standard_subs

cp-demint.o:
0000000000000001 C __gnu_lto_v1

cplus-dem.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 b char_str
0000000000000004 d cplus_markers
0000000000000000 D current_demangling_style
0000000000000000 R libiberty_demanglers
00000000000008a0 r operators.3870
0000000000000120 r optable

crc32.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 r crc32_table

dyn-string.o:
0000000000000001 C __gnu_lto_v1

fdmatch.o:
0000000000000001 C __gnu_lto_v1

fibheap.o:
0000000000000001 C __gnu_lto_v1

filename_cmp.o:
0000000000000001 C __gnu_lto_v1

getopt.o:
0000000000000001 C __gnu_lto_v1

getpwd.o:
0000000000000001 C __gnu_lto_v1
0000000000000008 b failure_errno.3555
0000000000000000 b pwd.3554

getruntime.o:
0000000000000001 C __gnu_lto_v1

floatformat.o:
0000000000000001 C __gnu_lto_v1
                 U floatformat_always_valid
0000000000000180 R floatformat_arm_ext_big
0000000000000140 R floatformat_arm_ext_littlebyte_bigword
00000000000002c0 R floatformat_i387_ext
                 U floatformat_i387_ext_is_valid
0000000000000240 R floatformat_i960_ext
0000000000000080 R floatformat_ia64_quad_big
0000000000000040 R floatformat_ia64_quad_little
0000000000000100 R floatformat_ia64_spill_big
00000000000000c0 R floatformat_ia64_spill_little
0000000000000000 R floatformat_ibm_long_double
                 U floatformat_ibm_long_double_is_valid
0000000000000440 R floatformat_ieee_double_big
0000000000000400 R floatformat_ieee_double_little
00000000000003c0 R floatformat_ieee_double_littlebyte_bigword
0000000000000540 R floatformat_ieee_half_big
0000000000000500 R floatformat_ieee_half_little
00000000000004c0 R floatformat_ieee_single_big
0000000000000480 R floatformat_ieee_single_little
0000000000000280 R floatformat_m68881_ext
0000000000000200 R floatformat_m88110_ext
00000000000001c0 R floatformat_m88110_harris_ext
0000000000000340 R floatformat_vax_d
0000000000000380 R floatformat_vax_f
0000000000000300 R floatformat_vax_g

fnmatch.o:
0000000000000001 C __gnu_lto_v1

fopen_unlocked.o:
0000000000000001 C __gnu_lto_v1

getopt1.o:
0000000000000001 C __gnu_lto_v1

hashtab.o:
0000000000000001 C __gnu_lto_v1
                 U eq_pointer
                 U hash_pointer
0000000000000000 D htab_eq_pointer
0000000000000008 D htab_hash_pointer
0000000000000000 r prime_tab

hex.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 R _hex_value

lbasename.o:
0000000000000001 C __gnu_lto_v1

lrealpath.o:
0000000000000001 C __gnu_lto_v1

make-relative-prefix.o:
0000000000000001 C __gnu_lto_v1

make-temp-file.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 b memoized_tmpdir
0000000000000012 r tmp
0000000000000009 r usrtmp
0000000000000000 r vartmp

md5.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 r fillbuf

objalloc.o:
0000000000000001 C __gnu_lto_v1

obstack.o:
0000000000000001 C __gnu_lto_v1

partition.o:
0000000000000001 C __gnu_lto_v1

pex-common.o:
0000000000000001 C __gnu_lto_v1

pexecute.o:
0000000000000001 C __gnu_lto_v1
0000000000000008 b idx
0000000000000000 b pex

pex-one.o:
0000000000000001 C __gnu_lto_v1

pex-unix.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 R funcs
                 U pex_unix_cleanup
                 U pex_unix_close
                 U pex_unix_exec_child
                 U pex_unix_fdopenr
                 U pex_unix_fdopenw
                 U pex_unix_open_read
                 U pex_unix_open_write
                 U pex_unix_pipe
                 U pex_unix_wait

physmem.o:
0000000000000001 C __gnu_lto_v1

regex.o:
0000000000000001 C __gnu_lto_v1
0000000000000100 b byte_reg_unset_dummy
0000000000000104 b done.2899
0000000000000120 b re_comp_buf
0000000000000000 r re_error_msgid
0000000000000000 b re_syntax_table
0000000000000000 D xre_max_failures
0000000000000008 C xre_syntax_options

safe-ctype.o:
0000000000000001 C __gnu_lto_v1
0000000000000200 R _sch_istable
0000000000000100 R _sch_tolower
0000000000000000 R _sch_toupper

sha1.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 r fillbuf

sort.o:
0000000000000001 C __gnu_lto_v1

spaces.o:
0000000000000001 C __gnu_lto_v1
0000000000000008 b buf.2321
0000000000000000 b maxsize.2322

splay-tree.o:
0000000000000001 C __gnu_lto_v1

strerror.o:
0000000000000001 C __gnu_lto_v1
0000000000000020 b buf.3175
0000000000000000 b error_names
0000000000000000 r error_table
0000000000000008 b num_error_names

strsignal.o:
0000000000000001 C __gnu_lto_v1
0000000000000020 b buf.3493
0000000000000008 b num_signal_names
0000000000000000 b signal_names
0000000000000020 r signal_table
0000000000000000 r sys_nsig

unlink-if-ordinary.o:
0000000000000001 C __gnu_lto_v1

xatexit.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 b xatexit_first
0000000000000000 d xatexit_head

xexit.o:
0000000000000001 C __gnu_lto_v1
0000000000000008 C _xexit_cleanup

xmalloc.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 b first_break
0000000000000000 d name

xmemdup.o:
0000000000000001 C __gnu_lto_v1

xstrdup.o:
0000000000000001 C __gnu_lto_v1

xstrerror.o:
0000000000000001 C __gnu_lto_v1
0000000000000000 b xstrerror_buf

xstrndup.o:
0000000000000001 C __gnu_lto_v1
[hjl@gnu-6 pr12004]$ 
Comment 11 Andi Kleen 2010-10-04 07:01:08 UTC
I think that's because you didn't strip the ELF symbol table,
so it will fall back to the ELF table.

If you only "ONLYLTO" first and there is only LTO information (see #6) it doesn't
work. 

Comment 12 Andi Kleen 2010-10-04 07:02:03 UTC
Created attachment 5032 [details]
test case demonstrating the ar problem

Full test case demonstrating the ar problem. 

You will need a lto capable gcc.
Please adjust the paths in the Makefile first.
Comment 13 H.J. Lu 2010-10-04 12:04:31 UTC
I got

[hjl@gnu-6 lto-ar-emu]$ make
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o main.o main.c
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o a.o a.c
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o b.o b.c
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o c.o c.c
./ONLYLTO a.o
./ONLYLTO b.o
./ONLYLTO c.o
rm -f t.a
./ar --plugin
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/liblto_plugin.so
qs t.a a.o.o b.o.o c.o.o
./ar: creating t.a
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -flto -fuse-linker-plugin 
main.o t.a   -o main
lto1: fatal error: Cannot find LTO varpool in t.a

compilation terminated.
lto-wrapper: /export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc returned 1 exit
status
/usr/local/bin/ld.gold: fatal error: lto-wrapper failed
collect2: ld returned 1 exit status
make: *** [main] Error 1
[hjl@gnu-6 lto-ar-emu]$ nm -s t.a

Archive index:
a in a.o.o
b in b.o.o
c in c.o.o

a.o.o:

b.o.o:

c.o.o:
[hjl@gnu-6 lto-ar-emu]$ 

It looks OK to me.
Comment 14 H.J. Lu 2010-10-04 12:21:31 UTC
ONLYLTO looks odd to me. I made some changes and got:

[hjl@gnu-6 lto-ar-emu]$ cat ONLYLTO
#!/bin/sh

for s in $(readelf -S --wide $1 | grep lto | sed -e "s/.*\(.gnu.lto_.*\)[
\t]*PROGBITS.*/\1/")
do
  sections="$sections -j $s"
done

objcopy $sections $1 $1.o
[hjl@gnu-6 lto-ar-emu]$ make
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o main.o main.c
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o a.o a.c
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o b.o b.c
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -O2 -flto    -c -o c.o c.c
./ONLYLTO a.o
./ONLYLTO b.o
./ONLYLTO c.o
rm -f t.a
./ar --plugin
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/liblto_plugin.so
qs t.a a.o.o b.o.o c.o.o
./ar: creating t.a
/export/build/gnu/gcc/release/usr/gcc-4.6.0/bin/gcc -flto -fuse-linker-plugin 
main.o t.a   -o main
./main
c 3
[hjl@gnu-6 lto-ar-emu]$