Frederic Cambus

Blog · Git · Contact

Toolchains adventures - Q3 2021

Toolchains

I've been keeping myself busy since I posted the "Diving into toolchains" article at the beginning of June, so here is an update detailing what I've been up to during the past couple of months.

At the end of June, I went through the FSF copyright assignment process for both Binutils and GDB, which now allows me to contribute larger changes to these codebases. I thus updated the NetBSD system call table in GDB, and added support to readelf for reading OpenBSD ELF core notes.

In Pkgsrc land, I packaged and imported mold, a new linker that is optimized for modern multi-core machines, and updated our binutils package to the latest version.

At the end of August, I attended the OpenBSD k2k21 hackathon, and one of the goals I had was to get source-based code coverage working in LLVM. The first part of this was to find how to allow the compiler driver to link against the libclang_rt.profile library when passing the -fprofile-instr-generate and -fcoverage-mapping options to Clang. Once I figured the magic incantation, I committed my change to src and sent it upstream where it got committed and backported to the LLVM 13 branch. With this part sorted, the next step was to build and ship the library in the base system. I added build infrastructure for the library in base, and linked it to the build. It is now enabled on architectures where Clang is built.

To illustrate what we can do with the source-based code coverage, let's take the following C program:

#include <stdio.h>

int
main()
{
	printf(" >o_/   >o_/   >o_/ \n");
	return 0;

	printf("*PAN!* *PAN!* *PAN!*\n");
}

Let's build and instrument it to emit profile data:

clang -fprofile-instr-generate -fcoverage-mapping ducks.c -o ducks

And we can now run it to collect and process profile data:

LLVM_PROFILE_FILE="ducks.profraw" ./ducks
llvm-profdata merge -sparse ducks.profraw -o ducks.profdata
llvm-cov show ./ducks -instr-profile=ducks.profdata

We can see that no ducks were harmed during this experiment:

Ducks profile

Coverage reports can also be created by llvm-cov:

llvm-cov report ./ducks -instr-profile=ducks.profdata

Filename                      Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/home/f/ducks/ducks.c               2                 1    50.00%           1                 0   100.00%           6                 1    83.33%
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                               2                 1    50.00%           1                 0   100.00%           6                 1    83.33%

Using the LLVM_PROFILE_FILE environment variable, it is possible to do several runs with different options and/or input files and get a new .profraw file each time. All those files can then be merged using llvm-profdata, which is pretty useful for doing coverage reports from unit tests.

On top of the OpenBSD related changes I've been contributing upstream to LLVM, I've been continuing my experiments with the build system. I've also been reading documentation about various parts of the toolchain, sending diffs when encountering mistakes or things which could be improved.

binutils and GDB commits:

Pkgsrc toolchains related commits:

LLVM commits: