|go text: || - index - problems - systems - libraries - converting - [ programming ] - old library - new library - links -
||topics: || - largefile default - off_t in headers - [ make export64 ] - find mismatch - the autowrappers - environ changes - best practice? - export64 - mixmode code

export64 - mixmode code

here's the mail that was originally sent to the autoconf group just after I had been portint my zziplib 0.10.77 into the mixmode world to support both 32bit and 64bit models with the same library code. That description is not complete but should help you quite a bit:

* The library problem ...

As you see, the AC_SYS_LARGEFILE call will make these
binaries to be linked with different symbols compiled
into the base libraries (glibc here). That is easily
achieved by specific forms in the header files of the
C library which boils down to

#if !defined _LP64 && _FILE_OFFSET_BITS+0 == 64
#define lseek lseek64
#endif

and the glibc maintainers have ensured that any call
to (32bit type) lseek will be converted into a call
to the actual lseek64, simply because the underlying
unix kernel uses 64bit fileoffsets natively, it's
just that some arguments have to be checked. In
effect, the library exports two lseek symbols:

$ objdump -T /lib/libc.so.6 | grep " lseek"
000bf9a0  w   DF .text  0000003d  GLIBC_2.0   lseek
000cba90  w   DF .text  00000088  GLIBC_2.1   lseek64

* Third party libraries....

While this sounds logical, how would you guide a
developer of a third-party library to support this
dual-mode off_t field. And how can autoconf support
it actually.

First of all, the AC_SYS_LARGEFILE macro is a bit
short-sighted - it does simply enable 64bit off_t
but it does so on either freebsd system where this
is native and on linux system where it is optional.
However, on linux system we want the 64bit variant
of library calls to be named slightly differently.

http://ac-archive.sf.net/guidod/ac_sys_largefile_sensitive.html

has been build on top of it to AC_DEFINE an extra
symbol called LARGEFILE_SENSITIVE which guides the
library maker to the knowledege that this system
is actually off_t/off64_t sensitive. In the header
file of his library, he may write now:

#if defined LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 == 64
#define my_seek my_seek64
#define my_open my_open64
#endif

An application linking to the library will now be
made to link with the *64 variants, and the library
itself will provide them if being compiled as a
largefile variant. If the application and library
are both in 32bit then they will also link correctly,
but when they mismatch... then the linkage will fail,
i.e.
    ld: my_open not found
and doing a grep on the system table of the library
will reveal a symbol my_open64.

* Combined exports...

this scheme can be extended however - when the library
sources detect a LARGEFILE_SENSITIVE system and that it
is being compiled as _LARGEFILE_SOURCE then it can
choose to export a catch-call symbol as well.

off_t my_lseek (int fd, off_t offs, int whence)
{ ..... }

#if defined LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 == 64
#undef my_lseek /* has been diverted to my_lseek64 */
long my_lseek (int fd, long offs, int whence)
{
     off_t off = my_lseek64 (fd, offs, whence);
     offs = off;
     if (offs != off) { errno=EOVERFLOW; return -1; }
     return offs;
}
#endif


* Conclusions....

Well, what do you want - the 32bit off_t in a largefile unix98
is definitly a bad choice from the beginning. It is always
questionable whether it is good choice to extend the lifetime
of this nuisiance. On the other hand, there is sometimes the
need to create and maintain a library that may be regarded as
a "base library" for many programs and which should therefore
support the ability to -Define an off_t type and size.