Now let’s imagine this scenario: we have a kernel object full of ubiquitous types like uid_t, ushort, struct proc and so on. And with this kernel, we have a dozen of kernel modules built, mostly sharing numerous types with the kernel base. Needless to say, this can apply also to some userland application setups. Without any post-processing, both the modules and the kernel would have generated own CTF data. You can probably see now, that this causes unnecessary duplication. And that is exactly when uniquification comes into play.

It is done using the ctfmerge tool. Normally, we use it to take a set of objects and merge it into one with while making sure there is only one occurrence of each type. But this would not be enough, we still want to specify the parent file that we uniquify against. This saves a large portion of the space (currently, I have no estimate, there should be some post in the future with charts). Now, we need to realise this is not without problems – just imagine that we want to update the parent object, without even touching the children objects. Worry do not, there is one special switch in the ctfmerge that provides us the additive merge. One of the next blogposts will be exactly about this.

It seems that none of my kernel objects that were made during the CTF kernel build contain any references to the merging, simply the output of this command is either “cth_parname = (anon)” or a self-reference to the CTF header struct. Another evidence of this is simply looking at the kernel objects with the ctfdump – each one of them contains type definitions for common int or void.

After searching for usage of the ctfmerge in the system makefiles, I found that every time it is contained only as a body of an if which checks the MK_CTF variable for the “no” value. It seems that the file /usr/share/mk/bsd.own.mk contains the definition of this variable and sets it to be “no”. I will have to play some more with this.