autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AC_C_BIGENDIAN: grep'ing an object file


From: Alexandre Duret-Lutz
Subject: AC_C_BIGENDIAN: grep'ing an object file
Date: 08 Oct 2000 11:02:39 +0200
User-agent: Gnus/5.0807 (Gnus v5.8.7) Emacs/20.7

Hi,

Here is (probably a first version of) a set of patches that
implements Guido's idea of grep'ing a object file to determine
endianess when cross-compiling.  This has been discussed one 
month ago on the autoconf mailing list 
(see http://sources.redhat.com/ml/autoconf/2000-09/msg00065.html).

Guido did not have the time to make the patches but already
wrote the editorial text I'm quoting below.

There are three patches.

1) The first patch transform the macro body from this:

      bigendian=unknown
      if (param.h is usable)
         bigendian=(test with param.h)
      if (bigendian==unknown)
         bigendian=(AC_TRY_RUN a test)

to this:

      if (param.h is usable)
         bigendian=(test with param.h)
      else
         bigendian=(AC_TRY_RUN a test)

2) the second one implements Guido's idea, described below
   (of course Guido is not responsible for the errors I may have made).

3) the third patch adds optionnal arguments ACTION-IF-TRUE, 
   ACTION-IF-FALSE and ACTION-IF-UNKNOWN.  The default case
   requested by Caolan NcMara
   (http://sources.redhat.com/ml/autoconf/2000-09/msg00094.html)
   can be obtained by

   AC_C_BIGENDIAN(,,:)                            dnl default to little-endian
or
   AC_C_BIGENDIAN(,,[AC_DEFINE(WORDS_BIGENDIAN)]) dnl default to big-endian

>>> "gd" == Guido Draheim <address@hidden> writes:

 gd> abstract:
 gd> extend the tail of AC_C_BIGENDIAN with another test that does not 
 gd> need to execute a conftest-binary. The test compiles into conftest.o
 gd> and greps for some wellknown patterns. Currently-used host/target 
 gd> platform-pairs will always find the correct result, otherwise the
 gd> old behaviour of AC_C_BIGENDIAN is used.

 gd> current state:
 gd> the current AC_C_BIGENDIAN tries to compile and execute a C-text
 gd> in order to detect the target-endianness. This fails for case of
 gd> cross-compiling. There is the option of providing a default at the
 gd> autoconf-macro instantiation, otherwise it does throw right away.

 gd> Most instantiations of AC_C_BIGENDAIN will not provide a default
 gd> since the target-default cannot be guessed for the global village
 gd> in advance. If the bigendian-tests fail then the user of the
 gd> autoconf'ed package can change the configure.in to add a default
 gd> value that holds for the limited set of target-machines in his lab.

 gd> There remains the need for configure commandline-option that could 
 gd> make an explicit endian-notice on the configure-invokation, e.g.
 gd> something like --ac-* where all unknown sub-options are silently
 gd> ignored. This is not addressed by this patch.

 gd> the proposition:
 gd> The actual idea is to build an array of shorts filled with
 gd> integer-literals that are pairs of ascii/ebcdic chars combined
 gd> into 16bit (i.e. with an 8bit offset). The created short-array
 gd> fills a static data-portion visible in the binary. This 
 gd> data-portion does exhibit also as an ascii/ebcdic pattern.
 gd> The order of data-storage determines whether either the
 gd> littleendian or bigendian pattern is visible in the linear
 gd> order that the shell-string argument to grep gets encoded,
 gd> - or just byteswapped so that it is not seen by the grep
 gd> with its linear pattern. 

 gd> The actual code is more obvious than this theoretic description:

# try to guess the endianess by grep'ing values into an object file
  AC_LANG_CONFTEST(
[short ascii_mm[[]] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
short ascii_ii[[]] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
short ebcdic_ii[[]] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
short ebcdic_mm[[]] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
int main() { _ascii (); _ebcdic (); return 0; }])
  ac_cv_c_bigendian=unknown
  if AC_TRY_EVAL([ac_compile]) && test -s conftest.$ac_objext; then
    if test `grep -l BIGenDianSyS conftest.$ac_objext` ; then
      ac_cv_c_bigendian=yes
    fi
    if test `grep -l LiTTleEnDian conftest.$ac_objext` ; then
      if test "$ac_cv_c_bigendian" = unknown; then
        ac_cv_c_bigendian=no
      else
        # finding both strings is unlikely to happen, but who knows?
        ac_cv_c_bigendian=unknown
      fi
    fi
  else
    echo "configure: failed program was:" >&AC_FD_LOG
    cat conftest.$ac_ext >&AC_FD_LOG
  fi
  rm -f conftest.$ac_objext conftest.$ac_ext

 gd> The pattern must be different from any possible pattern that
 gd> could be stored in a simple objectcode, so the pattern must
 gd> be long enough and it must have a form not present in any 
 gd> known codepiece that could eventually statically be bound into
 gd> some simple objectcode, so "BIGENDIAN" does not count as a
 gd> valid pattern.

 gd> the limitations:
 gd> the code assumes sizeof(address@hidden) == 2*sizeof(address@hidden),
 gd> which corresponds to the machines in use, where sizeof(short) == 16bit
 gd> and shell-scripts are stored in 8bit, either ascii or ebcdic.
 gd> Otherwise the test fails and requires an explicit order.

 gd> sizeof(short) == 16bit is foremost an assumption that has a remarkable
 gd> history of being asserted in computer machinery. Even some old machines
 gd> with sizeof(char) or sizeof(*(void*)) == 16bit had such a 16bit short,
 gd> and today's computer manufacturers are known to design general purpose
 gd> processors as sizeof(*(void*)) == 8bit. There could be however some
 gd> some special machines with sizeof(*(void*)) > 16bit which would in 
 gd> turn make it a sizeof(short) > 16bit, just think of a DSP (or RIP)
 gd> with a specialized C compiler that has sizeof(short) == 24bit and 
 gd> sizeof(long) == 48bit. The shorts would then be padded with zeros which
 gd> is not nice to grep for. The amount of autoconf' packages that are
 gd> actually useable with such specialized C compilers is quite questionable.
 gd> Does config.sub contain already such a target-machine? not AFAIK.

 gd> Assuming the host-platform to execute scripts in 8bit does currently hold,
 gd> the only possible successor would be 16bit unicode. Since 16bit unicode is
 gd> the only known possible successor to current compile-platforms, the 
 gd> restriction to ascii/ebcdic as 8bit encodings can be safely assumed. The
 gd> supplied C-text would need an additional pattern for such machines, but
 gd> the howto-implement could be not easily answered so far.

 gd> summary:
 gd> The patch does solve the problems of all crosscompiling setups in the
 gd> year 2000 IMHO.

        * aclang.m4 (AC_C_BIGENDIAN): Move the AC_TRY_RUN call to the
        ACTION-IF-NOT-FOUND argument of AC_TRY_COMPILE, this suppress the
        need to initialize ac_cv_c_bigendian.

Attachment: ac_be.patch.1
Description: Text Data

        * aclang.m4 (AC_C_BIGENDIAN): Implement Guido Draheim's idea to
        guess endianess by grep'ing values into an object file when
        cross-compiling.

Attachment: ac_be.patch.2b
Description: Text Data

        * aclang.m4 (AC_C_BIGENDIAN): Handle ACTION-IF-TRUE, 
        ACTION-IF-FALSE and ACTION-IF-UNKNOWN.
        * doc/autoconf.texi (C Compiler Characteristics): Update
        documentation for AC_C_BIGENDIAN.

Attachment: ac_be.patch.3
Description: Text Data

Thanks,
-- 
Alexandre Duret-Lutz

reply via email to

[Prev in Thread] Current Thread [Next in Thread]