The Mali Offline Shader Compiler or malisc is an offline compiler, which is meant to create binaries which are loaded at runtime using the ARM_mali_shader_binary extension, in order to avoid the overhead of compiling at program-load time. For our purposes, it can be used to reverse-engineer the ISA without having to rely on an emulator or a mali-equipped device. There is a clause in the license which says that you can't reverse engineer the compiler; however, the consensus seems to be that using it to reverse-engineer the ISA (without actually disassembling it) is legal, or at least as legal as using

File Format

The file format that malisc produces is very simple - it seems to be similar to the RIFF format, however the chunks can be nested without the special RIFF tag.

The file is grouped into a tree of "chunks". Each chunk consists of the tag - 4 characters packed into a 32-bit int, then another 32-bit int which is the length of the data, then the data itself (which may contain other chunks). As for what the chunks mean, it's pretty much the same as the online compiler - see /limare/lib/program.c on how to interpret it. In addition, there are a few other tags:

MBS1 is the root chunk, which covers the entire file. It has one child, either CVER for vertex shaders or CFRA for fragment shaders. After the vertex, attribute and/or uniform streams, DBIN holds the program binary itself.

Full documentation can be found at MBS+File+Format.

Extracting the program binary

There's a tool in our git tree called mbs_dump which will dump out an MBS file in a readable form, it also takes various options for how to disassemble/decompile the fragment/vertex code. For more info on this tool and how to use it read Lima+Assembler.

Reverse Engineering

It turns out that the Mali developers were kind enough to leave all the debug symbols in the final binary, and their underlying code is clean enough that it's possible to see a lot of what's going on just via the function/symbol names.

To view the symbols do the following:

objdump -t `which malisc`