Subject: Re: Is detecting endianness at compile-time unworkable?

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Tue, 31 Jul 2018 16:25:24 +0200

On Tue, Jul 31 2018, Michael Felt wrote:

> I hope a I have a "leap forward"
>
>
> On 7/30/2018 11:39 AM, Ævar Arnfjörð Bjarmason wrote:
>> Perhaps it's worth taking a step back here and thinking about whether
>> this whole thing is unworkable. It was hard enough to get this to work
>> on the combination of Linux, *BSD and Solaris, but I suspect we'll run
>> into increasingly obscure platforms where this is hard or impossible
>> (AIX, HP/UX etc.)
> While I still cannot say for HP/UX it does seem there is a potential
> solution based on the status for _LITTLE_ENDIAN and _BIG_ENDIAN. At
> least, gcc on POWER and xlc on POWER provides one or the other - and my
> hope is that gcc on other platforms also provides them.

Yeah with GCC this is relatively easy, see
https://github.com/cr-marcstevens/sha1collisiondetection/blame/c3e1304/lib/sha1.c#L29-L115

> For "other" compilers that do not provide them - a modification to
> CFLAGS to define one or the other should make "make" work.
>
> Details (note - I am not a programmer, so by definition at least one of
> my "macros" will be wrong :)
>
> AIX and xlc
> root@x066:[/]xlc -qshowmacros -E /dev/null | grep -i endi
> 1506-297 (S) Unable to open input file null. A file or directory in the
> path name does not exist..
> #define __HHW_BIG_ENDIAN__ 1
> #define __BIG_ENDIAN__ 1
> #define __THW_BIG_ENDIAN__ 1
> #define _BIG_ENDIAN 1
>
> On SLES12 (le) and xlc
> suse12test:~/images/littleEndian/sles # xlc -qshowmacros -dM -E x.c |
> grep -i endi
> #define _LITTLE_ENDIAN 1
> #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
> #define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
> #define __LITTLE_ENDIAN__ 1
> #define __ORDER_BIG_ENDIAN__ 4321
> #define __ORDER_LITTLE_ENDIAN__ 1234
> #define __ORDER_PDP_ENDIAN__ 3412
> #define __VEC_ELEMENT_REG_ORDER__ __ORDER_LITTLE_ENDIAN__
>
>
> Based on what I can see on gcc on POWER and xlc on POWER I think an
> approach (simplified) can be:
>
> #if undefined(_BIG_ENDIAN) && undef(_LITTLE_ENDIAN)
> #error "one of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined. Try adding
> the correct value to CFLAGS"
> #else defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
> #error "Only one of _BIG_ENDIAN and _LITTLE_ENDIAN may be defined, not both"
> #endif
>
> And then logic based on the value set.
> This should also make cross-compile possible by unsetting an incorrect
> default and setting the correct value.

...the real trick is using these macros outside of GCC / glibc and on
older GCC versions. See the github link above, you basically end up with
a whitelist of how it looks on different systems / compilers. Sometimes
both are defined, sometimes only both etc.

It can be done, but as that code shows it's somewhat complex macro soup
to get right.

> p.s. Is there a setting I need to set somewhere so I receive a copy of
> the email sent after it is received by the list. I could send myself a
> copy, but I much prefer it comes from the maillist - as verification it
> was received.

You should get that, but maybe your mailer ignores Message-Ids it
already has, but you can go to https://public-inbox.org/git/ and search
for the Message-Id or your name to see E-Mails you've sent that made it
to the list, e.g.:
https://public-inbox.org/git/?q=aixtools%40felt.demon.nl