Expose symbols in lib/libclang_rt/profile to fix --coverage...
This fixes --coverage with libclang_rt.
MFC after: 1 month
Sponsored by: Dell EMC Isilon
Differential D9168
Expose symbols in lib/libclang_rt/profile to fix --coverage... ngie on Jan 13 2017, 10:10 AM. Authored by Tags None Referenced Files
Details Expose symbols in lib/libclang_rt/profile to fix --coverage... This fixes --coverage with libclang_rt. MFC after: 1 month Generating coverage numbers now works with zero hacks using the system $ make -s obj; make -s depend; make -s all; make get-coverage ===> lib (obj) ===> bin (obj) ===> lib (depend) ===> bin (depend) ===> lib (all) ===> bin (all) LD_LIBRARY_PATH=/usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/bin/foo This is foo lcov --capture --directory /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd --output-file /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/coverage.info Capturing coverage data from /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd Found gcov version: 4.2.1 Scanning /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd for .gcda files ... Found 2 data files in /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd Processing lib/foo.gcda /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib/foo.gcno:version '402*', prefer '402p' /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib/foo.gcda:version '402*', prefer version '402p' Processing bin/foo.gcda /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/bin/foo.gcno:version '402*', prefer '402p' /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/bin/foo.gcda:version '402*', prefer version '402p' Finished .info-file creation genhtml /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/coverage.info --output-directory output Reading data file /usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/coverage.info Found 2 entries. Found common filename prefix "/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd" Writing .css and .png files. Generating output. Processing file bin/foo.c Processing file lib/foo.c Writing directory view page. Overall coverage rate: lines......: 75.0% (3 of 4 lines) functions..: 100.0% (2 of 2 functions) $
Diff Detail
Event TimelineComment Actions As far as I can tell, upstream not setting the visibility flags for the .c files in the profile library is some sort of mistake. It looks like the intent has always been to hide all symbols in all of the compiler-rt libraries, wherever possible. Also, I am still unsure as to what this fixes, exactly. Why would something external want to reference internal symbols in this profiling library? Comment Actions Let me expand on this. If you look at the static libraries, the port copy of libprofile_rt's APIs are public, whereas the base system copy of libprofile_rt's APIs are private: Base system copy: % objdump -t /usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.profile-x86_64.a | grep llvm_gcda 0000000000000880 g F .text 0000000000000376 .hidden llvm_gcda_emit_arcs 0000000000000420 g F .text 0000000000000454 .hidden llvm_gcda_emit_function 00000000000010b0 g F .text 000000000000016f .hidden llvm_gcda_end_file 0000000000000400 g F .text 000000000000001e .hidden llvm_gcda_increment_indirect_counter 0000000000000000 g F .text 00000000000003fb .hidden llvm_gcda_start_file 0000000000000c00 g F .text 00000000000004a6 .hidden llvm_gcda_summary_info ... The port copy: % objdump -t /usr/local/llvm38/lib/clang/3.8.1/lib/freebsd/libclang_rt.profile-x86_64.a | grep llvm_gcda 00000000000008e0 g F .text 0000000000000348 llvm_gcda_emit_arcs 00000000000004b0 g F .text 0000000000000424 llvm_gcda_emit_function 00000000000013b0 g F .text 000000000000019a llvm_gcda_end_file 0000000000000490 g F .text 000000000000001e llvm_gcda_increment_indirect_counter 0000000000000000 g F .text 000000000000048e llvm_gcda_start_file 0000000000000c30 g F .text 000000000000077a llvm_gcda_summary_info These symbols being hidden makes it impossible for the clang toolchain to use them when the user specifies --coverage, e.g. % make CC=cc ===> lib (all) ===> bin (all) cc -O2 -pipe -I/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib --coverage -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -L/usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib -Wl,-rpath-link,/usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib -o foo.full foo.o -lfoo /usr/bin/ld: foo.full: hidden symbol `llvm_gcda_emit_arcs' in /usr/bin/../lib/clang/3.9.1/lib/freebsd/libclang_rt.profile-x86_64.a(GCDAProfiling.o) is referenced by DSO /usr/bin/ld: final link failed: Nonrepresentable section on output cc: error: linker command failed with exit code 1 (use -v to see invocation) *** Error code 1 Stop. make[1]: stopped in /home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/bin *** Error code 1 Stop. make: stopped in /home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd % vs % make CC=/usr/local/bin/clang38 ===> lib (all) ===> bin (all) /usr/local/bin/clang38 -O2 -pipe -I/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib --coverage -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -L/usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib -Wl,-rpath-link,/usr/obj/home/ngie/nfs/git/scratch/coverage-with-shared-libs-freebsd/lib -o foo.full foo.o -lfoo objcopy --only-keep-debug foo.full foo.debug objcopy --strip-debug --add-gnu-debuglink=foo.debug foo.full foo % We have been working around this symbol issue for 4 releases now at work by using a specially configured/built copy of libprofile_rt because we weren't aware of the symbol hiding. Once I remove the symbol hiding, things just work with the copy of clang in base with this library. Comment Actions ...
profile_rt isn't the only library -- it looks like everything except asan-preinit is exposed publicly: $ for i in /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/*.a; do objdump -t $i | grep -q hidden && echo $i || echo not $i; done not /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.builtins-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.dd-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.lsan-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.profile-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.safestack-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.stats-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.stats_client-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.tsan-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a /usr/local/llvm39/lib/clang/3.9.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a % Comment Actions In retrospect, these CFLAGS are incorrect -- the libraries already specify visibility attributes via COMPILER_RT_VISIBILITY, etc. I'm just going to delete the lines and see what happens. Comment Actions ...
Here are the rationale for the -fvisibility lines, which have been carried on to today: $ svn log -c 215129 ------------------------------------------------------------------------ r215129 | ed | 2010-11-11 08:53:25 -0800 (Thu, 11 Nov 2010) | 7 lines Set symbol visibility to hidden. Not doing so may cause all sorts of random libraries to expose libcompiler_rt's functions, which should of course not be done. Discussed with: kan, kib ------------------------------------------------------------------------ libcompiler_rt used to be installed to /usr/lib, so this rationale made sense, however -- all of the libclang_rt libraries are private to clang's lib directory (you have to explicitly add the path to LDFLAGS, which is wrong in so many ways), so this is no longer an issue. Comment Actions I'm still not sure about this. I did an analysis of how upstream builds compiler-rt, and they are definitely using -fvisibility-inlines-hidden for all C++ sources (for C sources this flag is not functional). I don't think you ever want to export addresses of inline functions. Upstream also uses -fvisibility=hidden for the following parts of compiler-rt:
In fact the only parts where -fvisibility is not used, are:
I'm going to take a look at your previous diff now. Comment Actions Let's use this instead. I just tried building your coverage-with-shared-libs-freebsd project with it, and it worked fine. Comment Actions Thank you for the counter-proposal! Should the builtins library be handled this way as well? Comment Actions Please commandeer the revision back to yourself, and then you can commit it :)
Yes, maybe, though nobody yet complained about any symbols being hidden. @emaste, what's your opinion on this? |