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:

2021-09-11 98ca73a Add support to readelf for reading OpenBSD ELF core notes
2021-07-14 77db472 Update the NetBSD system call table to match NetBSD-current

Pkgsrc toolchains related commits:

2021-09-27 65675ea Update to mold 0.9.6
2021-09-11 871f328 Update to binutils 2.37
2021-09-11 53d0f2e Update to mold 0.9.5
2021-07-29 1b5d585 Import mold 0.9.3

LLVM commits:

2021-09-30 97a0ba4 [clang] Update Clang version from 13 to 14 in scan-build.1
2021-09-30 01641f6 [clang] Fix sentence in the usage section of ThinLTO docs
2021-09-29 7a7caf9 [clang] Fix library name (libsupc++) in the admonition note
2021-09-28 5b125a4 [CMake] Add detection for the mold linker in AddLLVM.cmake
2021-09-24 626e2a6 [compiler-rt] Use portable “#!/usr/bin/env bash” shebang for tests
2021-09-24 4ed0531 [docs] Document the –print-passes flag in opt
2021-09-23 7f5ca8c [clang] Use portable “#!/usr/bin/env bash” shebang for tools and utils
2021-09-17 b588f5d [clang][scan-build] Use cc/c++ instead of gcc/g++ on OpenBSD
2021-09-07 4787ef3 [compiler-rt] Document that builtins is known to work on OpenBSD
2021-09-03 466451c [clang] Allow the OpenBSD driver to link the libclang_rt.profile library
2021-07-27 1862ffe [clang] Fix a typo in the manual page: s/contraint/constraint
2021-07-23 bc96aa9 [clang] Fix typos in Options.td and regen ClangCommandLineReference.rst