I'm writing a program on Linux in C to analyze core files produced from an embedded system. The core files might be little endian (ARM) or big endian (MIPS), and the program to analyze them might be running on a little endian host (x86) or big endian (PowerPC).
By looking at the headers I know whether the core is LE or BE. I'd rather my program not need to know whether the host it runs on is little or big endian, I'd like to use an API to handle it for me. If there is no better option, I guess I'll start relying on #ifdef __BIG_ENDIAN__.
In the Linux kernel we have cpu_to_le32 et al to convert from native byte ordering to little endian, etc. In user space there is htonl et al, which convert from native to big endian but no equivalent for native to little endian that I can find.
Can anyone suggest a suitable API for user space?
Edit: Just to be clear, I'm looking for an API which already knows whether my CPU is big or little endian and swaps byes accordingly. I don't want to have to litter my code with #ifdefs for this. I'm not just looking for code snippets to swap bytes; thank you for those, but that wasn't the point.
Given that switching endian-ess is easy, I always ended up using custom code like that, keeping a strict rule about what representation I use in the code, and handling endianity at the end points (input and output).
#include <arpa/inet.h>
is nice and portable, but only guarantees{ntoh,hton}{s,l}
. If you need conversions on 64-bit values, or endian flipping on big-endian (wherentoh
andhton
do nothing), it won't be enough.On Linux (glibc),
#include <endian.h>
provides the following, defined as appropriate for the current machine.On *BSD,
#include <sys/endian.h>
provides these same macros.If you have access to the neon coprocessor and the memory is contiguous (example a video frame) you could execute swap16 on the frame using the q registers (128bytes) in this way; of course, you have to watch for alignment issues
Why do you need an API to do it? Simply write your own function to call
htonl()
(or whatever produces BE) then simply reverse the bytes. That doesn't sound so hard.Something like:
Based on what you're actually trying to do (read ELF core dump files without having to worry about endian issues), I believe using libelf, available here with a nice tutorial here, would be a good choice.
This library works transparently with big- and little-endian ELF files and runs just fine under Linux despite its FreeBSD origins (the usual "./configure" and "make" sequence is all you'll need to build it). For grins I tried the "reading a program header table" example (with minor modifications to get it to build) on an x86 core file as well as a MIPS big-endian core file, it appears to "just work".
Take a look at the kernel-provided headers in /usr/include/linux/byteorder/ such as __cpu_to_be32() and __be32_to_cpu()
Take also a look at the /usr/include/linux/types.h file where you can define types as explicit big/little endian plain integers, which help a lot since any mismatch will be detected at compile time.