As per the slides, there are 5 main subsystems we had to build:
We chose early on to write just about all of this from scratch (insert “there are now N+1 competing standards” joke here) for a couple of reasons:
- Performance - all of warpcore is written in C++
- Customizability - we want to develop this in chunks which means having a simple, stable API for each piece
- Non-existence - a lot of the things we need don’t exist
I wrote a super rudimentary ELF parser in a night or two sometime in the fall of 2017 before the project really started up. As mentioned in the slides, this is now the second ELF parser I’ve written - the other was for an early version of dispatch.
It’s not fancy at all and just parses enough of the file to load data into our memory model.
My primary role in the project has been writing a compiler/transpiler which takes in ARM’s machine readable architecture specification (written in ASL) and emits C++, which in turn builds IL expressions.
At a 10,000ft level, here’s what happens:
- Use the fantastic lark parser Python library to parse the ASL into a tree. ARM’s own Alastair Reid has done most of the grammer-writing work for us in his mra_tools repo.
- Convert this parse tree into another tree more suitable for working with, and begin to keep track of variable declarations, typing information, etc. since ASL types are not always explicit (i.e. variable types may have to be inferred).
- Fix-up the tree (e.g. re-order binary operator expressions to account for operator precedence)
- Propogate concrete/symbolic constraints around.
- Emit C++.
We’re hoping to open-source this code near the end of the year, and I’ll write much more about the transpiler then.