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

Re: [PATCH] Provide __errno_location and friends like LinuxThreads

On Thu, Oct 31, 2002 at 08:02:39PM -0800, Roland McGrath wrote:
> This should not be required, because the main libc sources should define
> those already when building for __thread.  You should figure out why that
> is not happening.  __errno_location is in csu/errno-loc, __h_errno_location
> in inet/herrno.

Unfortunately it is needed in libpthread.so because of symbol versioning.
Say with:
cat > test.c <<EOF
#include <errno.h>
int foo (void)
  return errno;
gcc -shared -o test.so test.c -lpthread
readelf -Wa test.so says:
    26: 00000000    21 FUNC    GLOBAL DEFAULT  UND __errno_location GLIBC_2 0 (2)
    27: 0000059c     0 FUNC    GLOBAL DEFAULT    8 _init
    28: 00001820     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    29: 000006f4     0 FUNC    GLOBAL DEFAULT   11 _fini
    30: 00000000   152 FUNC    WEAK   DEFAULT  UND __cxa_finalize GLIBC_2 1 3 (3)
Version needs section '.gnu.version_r' contains 2 entries:
 Addr: 0x000000000000051c  Offset: 0x00051c  Link to section: 3 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 1
  0x0010: Name: GLIBC_2.1.3  Flags: none  Version: 3
  0x0020: Version: 1  File: libpthread.so.0  Cnt: 1
  0x0030: Name: GLIBC_2.0  Flags: none  Version: 2

ld.so doesn't allow moving of versioned symbols:

The relevant code is in do-lookup.h:
      /* If this current map is the one mentioned in the verneed entry
         and we have not found a weak entry, it is a bug.  */
      if (symidx == STN_UNDEF && version->filename != NULL
          && __builtin_expect (_dl_name_match_p (version->filename, map), 0))
        return -1;
and dl-lookup.c:
      if (__builtin_expect (res, 0) < 0)
          /* Oh, oh.  The file named in the relocation entry does not
             contain the needed symbol.  */
          const char *reference_name = undef_map ? undef_map->l_name : NULL;

          /* XXX We cannot translate the message.  */
          _dl_signal_cerror (0, (reference_name[0]
                                 ? reference_name
                                 : (rtld_progname ?: "<main program>")),
                             N_("relocation error"),
                             make_string ("symbol ", undef_name, ", version ",
                                          " not defined in file ",
                                          " with link time reference",
                                          res == -2
                                          ? " (no version symbols)" : ""));
          *ref = NULL;
          return 0;

If we made __errno_location a strong symbol, not weak, if
USE_TLS && HAVE___THREAD (which is IMHO a good idea no matter what),
then it would fix the case where libc.so is earlier in the search path than
libpthread.so, but that is not the desirable order where libpthread.so is
looked up before libc.so.

 #if !(USE_TLS && HAVE___THREAD)
 #undef errno
 extern int errno;
 int *
+#if !(USE_TLS && HAVE___THREAD)
 __errno_location (void)
   return &errno;


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