If you work on PowerPC systems of some kind – or maybe you work on car MCUs that use the NEC V800 CPU – you may have run across some strange output when you run the file command on any binary:
/usr/bin/file: ELF 32-bit MSB pie executable, PowerPC or cisco 4500, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-powerpc.so.1, stripped
Of course it’s a PowerPC binary, but why the mention of “cisco 4500” (or Cisco 7500s for 64-bit PowerPC binaries, or Cisco 12000s for NEC V800s)? The reason behind this is a fascinating insight into the world of proprietary computing architectures and the somewhat inventive way Cisco tried to lock down some of their older systems.
A brief primer on ELF
ELF, which stands for Extensible Linking Format or Executable and Linkable Format and is not a Will Ferrell character, is a file format for executable files and shared libraries (among others).
In layman’s terms, ELF specifies things like what processor the executable runs on, the ABI that it uses, the endianness and word size (32-bit or 64-bit, for example) that it uses, and so on.
One of the fields in an ELF file is the e_machine field, which specifies the type of machine the file is designed to run on. 0x02 is SPARC, 0x03 is the Intel x86, 0x14 is 32-bit PowerPC, 0x15 is 64-bit PowerPC, and so on.
This is the identifier that allows your OS to tell you “Exec format error” (or similar) when you run an executable for a CPU other than the one you are currently using. As a side note, it is also this field that allows qemu-user binfmt to work, if you are curious.
Cisco’s use of e_machine
The boot loader for Cisco IOS machines, also known as ROMMON, will refuse to load firmware for a different router model than the system. For example, on a Cisco 2911, you may see:
loadprog: error - Invalid image for platform
e_machine = 30, cpu_type = 194
ROMMON uses e_machine as a sort of “model number”. The Cisco 4500 uses cpu_type 20 or 0x14, which happens to also be the ELF e_machine for PowerPC.
The “magic” library that the file command uses to determine the machine type of ELF binaries only knows a few models of Cisco. I haven’t been able to determine their criteria for inclusion, or why some are present and some aren’t.
The ROMMON error was gleaned from an OpenWrt forum post; I don’t have hardware to show this error myself.
More information about how older Cisco devices use ELF can be found on the LinuxMIPS wiki.
This question was originally asked by some curious people on the #talos-workstation IRC channel on Libera.Chat. I knew the basics of Cisco’s ELF-scapades, but they were the ones who inspired me to make this write-up and learn a bit more.