[llvm-dev] Code coverage for baremetal microcontrollers

Friedman, Eli via llvm-dev llvm-dev at lists.llvm.org
Thu Oct 11 12:33:22 PDT 2018


On 10/10/2018 6:41 PM, Cody Addison via llvm-dev wrote:
> I am interested in using LLVM's code coverage on "baremetal" MCUs. The current code coverage support has the following drawbacks for MCUs:
>
> 1. 64-bit counters
> 2. All coverage sections (__llvm_prf_data, __llvm_prf_names, and __llvm_covmap) are expected to reside in target memory. This is so the runtime can write a raw coverage file to disk
> 3. The runtime is large and relies on system calls like mmap() which are not available on most MCU platforms.
>
> My proposal is to add a new "embedded" coverage capability with the following differences:
>
> 1. 32-bit counters
> 2. The __llvm_prf_data, __llvm_prf_names, and __llvm_covmap sections are in the object files, but without the SHF_ALLOC ELF section flag. I can do this by either having LLVM not set the SHF_ALLOC flag in the object file or by having the linker not set the SHF_ALLOC flag on the output sections. I'm not familiar with the other object file format supported in LLVM so inputs on how to handle this are welcome.
> 3. The runtime can be reduced to a very simple routine which simply writes the __llvm_prf_cnts section to a file. This function can support file names through a constant provided at link time, but will not allow changing the filename at runtime (no environment variables!). In my specific use case, it is highly likely that the user will use a debugger to read the counters from target memory so the runtime isn't required and will be optional.
> 4. Add the capability to llvm-profdata to create an indexed coverage file by reading the counters from a file and extracting the __llvm_prf_data and __llvm_prf_names sections from the ELF executable used to run the application. My current implementation uses the following command line:
>
>     > llvm-profdata merge -sparse -obj-file=a.out test.profcnts -o default.profdata
>
> After this the llvm-cov tool works as it always has. Also, I do not plan on supporting value profiling, at least initially.
>
> I've coded up a prototype implementation in llvm-profdata which was fairly straightforward and I am relying on my linker to avoid loading the sections on the target. I'm interested if anyone has had a similar proposal or thought about this issue in the past. If this is an acceptable feature, I'll work on submitting patches soon.

I've done coverage with baremetal before.  That said, the environment I 
was using was generous in terms of memory. I didn't worry about the size 
of the counters, or trying to stick __llvm_prf_data and  
__llvm_prf_names into a non-allocatable section.  So I mostly just used 
the existing runtime and workflow.

It's actually pretty easy to get the existing runtime to build in a 
baremetal environment; just some build system changes to exclude the 
unnecessary files.  I meant to clean up and submit the patch at some 
point, but never got around to it.

If you're using 32-bit counters, what do you do on overflow?  Or are you 
just ignoring the possibility?

-Eli

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project



More information about the llvm-dev mailing list