Avoiding function addresses in llvm_prf_data when value profiling is disabled

I encountered an issue when enabling code coverage for Android and would like to confirm my findings and ask for suggestions.

Here is my finding:

When -fprofile-instr-generate, an llvm_prf_data section gets created that has entries for each function in the TU. One of the entries is FunctionAddr which holds the address of the function. Underneath, it is a relocation so it gets patched with the runtime, in-memory address of the function. The whole llvm_prf_data section, or at least the FunctionAddr entry, is used only when value profiling is enabled.

Value profiling is disabled by default and can be enabled with -mllvm -enable-value-profiling.

My problem is below:

The FunctionAddr entries create references to all functions in the TU. This causes an issue with -ffunction-sections and -Wl,–gc-sections (which Android uses by default). The reference to functions causes the linker to retain all of these functions.

This causes build errors when enabling code coverage for Android because the build rules are written assuming --gc-sections is passed to the linker and do not specify all necessary libraries to ensure proper linking of the discarded sections.


I’m considering setting FunctionAddr to 0 if value profiling is disabled (or omitting llvm_prf_data altogether if it exists solely for value profiling). Does that sound reasonable?


Could we use !associated metadata and SHF_LINK_ORDER to make instr profiling work with gc-sections, as has been done for ASan global metadata?

That sounds like a good idea. Or when VP is disabled, avoid recording the function addresses.


I’ve done some work to enable --gc-sections to work with instr profiling in https://reviews.llvm.org/D64045, but I still need to write more tests before that change is ready to land.