A funny thing happened on the way to the Java bootstrap…

One of my best friends, Horst, is working on “bootstrapping” Java in the Adélie Linux distribution. This means we will be able to build the Java runtime entirely from source, not relying on binaries from Oracle or others – which means we can certify and trust that our Java is free from any third-party code. For a little “light reading” on this subject, see Ken Thompson’s seminal 1983 paper, Reflections on Trusting Trust, and the Bootstrappable Builds site.

Roughly, the Java bootstrap looks like this: build a very old Java runtime that was written in C++, use that to build a slightly less old Java runtime written in Java, and up from there. And while the very old Java runtime that he was using built fine on his AMD Ryzen system, and also seemed to work great on the Arm-based Raspberry Pi, it hung (locked up, froze) on my Power9-based Talos II.

Looking up JamVM on PowerPC systems, Horst found a Gentoo bug from 2007 that describes the issue exactly. There was no solution found by the Gentoo maintainers; they simply removed the ability of PPC64 computers to install the JamVM package.

This obviously wouldn’t do for us. Adélie treats the PPC64 architecture as tier-1: we have to make sure everything works on PPC64 systems. So, I dove into the code and began spelunking around for causes.

The code that ensures thread safety seemed to be at fault, but I couldn’t tease out the real issue at first. I built JamVM with ASAN and UBSAN and found a cavalcade of awfulness, including a home-grown memory allocator that was returning misaligned addresses. That’s sure to give us trouble if we ever endeavour towards SPARC. There were a few signedness errors and a single byte buffer-overrun as well.

I fixed all of those issues, and while JamVM was now “sanitiser-clean” and also reported no issues in Valgrind, it was still hanging. I added some debug statements to the COMPARE_AND_SWAP routine and found that no debugging happened. I thought that was odd, but then I saw the problem: the 64-bit code was set to only compile if “__ppc64__” was defined. Linux defines “__PPC64__”, in all-caps, not lowercase.

I changed that, and for good measure also fixed the types it uses for reading the swapped variable and returning the result, and recompiled. Lo and behold, JamVM was now working on my 64-bit PowerPC.

And that is how I accidentally stumbled upon, and fixed, a 17-year-old bug in an ancient Java runtime. That bug would have been old enough to drive…

The patch is presently fermenting in a branch in Adélie’s packages.git, but will eventually land as bootstrap/jamvm/ppc64-lock.patch.

2 thoughts on “A funny thing happened on the way to the Java bootstrap…”

Leave a comment