[TriLUG] Ten Little ENDIANS
Tarus Balog
tarus at sortova.com
Mon Mar 24 10:19:54 EST 2003
Gang:
I need some help with C on Solaris/Intel. Since this post is long and
slightly off-topic, feel free to hit delete now.
OpenNMS is written in Java, but because Java does not have an ICMP API
(which is important in network management) one was written in C and is
accessed via JNI.
Processors come in two main types with respect to byte order. Those that
list the most significant byte first are BIG_ENDIAN, whereas those that
list the least significant byte first are LITTLE_ENDIAN. Network data is
by default BIG_ENDIAN, regardless of the processor used.
Most RISC processors, like the SPARC, are BIG_ENDIAN, whereas Intel
processors are LITTLE_ENDIAN. This means that on Intel you have to swap
bytes received from the network in order for them to make sense.
We do this in the following code by creating a "network to host" macro.
Most LITTLE_ENDIAN systems seem to support the conversion of "long"
variable types, but don't seem to have macros for 64 bit "long long"
variable types, so we create our own: ntohll (network to host long long)
and htonll (host to network long long). Here's part of the code:
#if defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN) ||
defined(__LITTLE_ENDIAN__)
# ifndef ntohll
# if defined(__DARWIN__)
# define ntohll(_x_) NXSwapBigLongLongToHost(_x_)
# else
# define ntohll(_x_) __bswap_64(_x_)
# endif
# endif
For BIG_ENDIAN systems, it is just a null macro.
Now, notice that on DARWIN (Mac OS X) there is already a function defined
(where Ben Reed found it is beyond me as it is almost a googlewhack). On
Linux the function is __bswap_64.
So, my first try was to search for an equivalent function to __bswap_64 in
Solaris. No such luck. The "swab" function has potential, but I can't seem
to get it to work.
Then my next attempt was to get the GNU byteswap.h code to work on
Solaris/Intel. It compiles, but when I run it I get an undefined symbol
error on "__udivdi3".
This is supposed to be included in libgcc.a, which I now have symbolically
linked all over the place. I am also using GNU's ld and as. But still it
fails. Not being a C programmer, I am also confused by the fact that a
grep for "udivdi" in libgcc on Linux returns a match, whereas is fails on
Solaris/Intel. So I am not even sure my libgcc.a contains the function.
(Yes, I am grasping a bit here).
Has anyone else on the list run into a similar issue on Solaris/Intel? I
would appreciate any suggestions (outside of basing the box and installing
Linux [grin]).
-T
--
Tarus Balog
Consultant
Sortova Consulting Group, http://www.sortova.com
+1-919-696-7625
tarus at sortova.com
More information about the TriLUG
mailing list