[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