mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-17 14:10:10 +00:00
Update.
* sysdeps/libm-ieee754/e_gamma_r.c: Initialize *signgamp for NaN returns. * sysdeps/libm-ieee754/e_gammaf_r.c: Likewise. * sysdeps/libm-ieee754/e_gammal_r.c: Likewise. Reported by John Reiser <jreiser@BitWagon.com> [PR libc/1185]. * elf/dl-dst.h: Fix typo. * elf/dl-open.c: Likewise. 1999-06-26 Zack Weinberg <zack@rabi.columbia.edu> * elf/dl-libc.c: New file, provides three functions: __libc_dlopen, __libc_dlclose, __libc_dlsym. * include/dlfcn.h: Prototype them. Prototype _dl_addr. * elf/Makefile (routines): Add dl-libc.c. * elf/dl-profstub.c (_dl_mcount_wrapper): Change type of argument to void *. * elf/ldsodefs.h: Change proto and use of _dl_mcount_wrapper to match. * iconv/gconv.c: Include dlfcn.h. * iconv/gconv_db.c: Likewise. * malloc/mtrace.c: Likewise. Don't include ldsodefs.h. * iconv/gconv_int.h (struct __gconv_loaded_object): Change `handle' to a void *. (__gconv_find_func): Delete prototype. * iconv/gconv_dl.c: Don't include ldsodefs.h. Remove dlerror_run and related functions and structs. Use __libc_dlopen, __libc_dlsym, __libc_dlclose. * nss/nsswitch.c: Likewise. 1999-06-28 Ulrich Drepper <drepper@cygnus.com>
This commit is contained in:
parent
738d1a5a43
commit
b3fc5f84d1
34
ChangeLog
34
ChangeLog
@ -1,3 +1,37 @@
|
||||
1999-06-28 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* sysdeps/libm-ieee754/e_gamma_r.c: Initialize *signgamp for NaN
|
||||
returns.
|
||||
* sysdeps/libm-ieee754/e_gammaf_r.c: Likewise.
|
||||
* sysdeps/libm-ieee754/e_gammal_r.c: Likewise.
|
||||
Reported by John Reiser <jreiser@BitWagon.com> [PR libc/1185].
|
||||
|
||||
* elf/dl-dst.h: Fix typo.
|
||||
* elf/dl-open.c: Likewise.
|
||||
|
||||
1999-06-26 Zack Weinberg <zack@rabi.columbia.edu>
|
||||
|
||||
* elf/dl-libc.c: New file, provides three functions:
|
||||
__libc_dlopen, __libc_dlclose, __libc_dlsym.
|
||||
* include/dlfcn.h: Prototype them. Prototype _dl_addr.
|
||||
* elf/Makefile (routines): Add dl-libc.c.
|
||||
* elf/dl-profstub.c (_dl_mcount_wrapper): Change type of
|
||||
argument to void *.
|
||||
* elf/ldsodefs.h: Change proto and use of _dl_mcount_wrapper to match.
|
||||
|
||||
* iconv/gconv.c: Include dlfcn.h.
|
||||
* iconv/gconv_db.c: Likewise.
|
||||
* malloc/mtrace.c: Likewise. Don't include ldsodefs.h.
|
||||
|
||||
* iconv/gconv_int.h (struct __gconv_loaded_object): Change
|
||||
`handle' to a void *.
|
||||
(__gconv_find_func): Delete prototype.
|
||||
|
||||
* iconv/gconv_dl.c: Don't include ldsodefs.h. Remove
|
||||
dlerror_run and related functions and structs. Use
|
||||
__libc_dlopen, __libc_dlsym, __libc_dlclose.
|
||||
* nss/nsswitch.c: Likewise.
|
||||
|
||||
1999-06-28 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/gethostid.c: Test for gethostbyname_r
|
||||
|
@ -22,7 +22,7 @@ subdir := elf
|
||||
|
||||
headers = elf.h bits/elfclass.h bits/dlfcn.h link.h dlfcn.h
|
||||
routines = $(dl-routines) dl-open dl-close dl-symbol dl-support \
|
||||
dl-addr enbl-secure dl-profstub dl-origin
|
||||
dl-addr enbl-secure dl-profstub dl-origin dl-libc
|
||||
|
||||
# The core dynamic linking functions are in libc for the static and
|
||||
# profiled libraries.
|
||||
|
@ -33,7 +33,7 @@
|
||||
extern size_t _dl_dst_count (const char *name, int is_path);
|
||||
|
||||
|
||||
/* Guess from the number of DSTs the length of the restul string. */
|
||||
/* Guess from the number of DSTs the length of the result string. */
|
||||
#define DL_DST_REQUIRED(l, name, len, cnt) \
|
||||
({ \
|
||||
size_t origin_len; \
|
||||
|
122
elf/dl-libc.c
Normal file
122
elf/dl-libc.c
Normal file
@ -0,0 +1,122 @@
|
||||
/* Handle loading and unloading shared objects for internal libc purposes.
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
/* The purpose of this file is to provide wrappers around the dynamic
|
||||
linker error mechanism (similar to dlopen() et al in libdl) which
|
||||
are usable from within libc. Generally we want to throw away the
|
||||
string that dlerror() would return and just pass back a null pointer
|
||||
for errors. This also lets the rest of libc not know about the error
|
||||
handling mechanism.
|
||||
|
||||
Much of this code came from gconv_dl.c with slight modifications. */
|
||||
|
||||
static int
|
||||
internal_function
|
||||
dlerror_run (void (*operate) (void *), void *args)
|
||||
{
|
||||
char *last_errstring = NULL;
|
||||
int result;
|
||||
|
||||
(void) _dl_catch_error (&last_errstring, operate, args);
|
||||
|
||||
result = last_errstring != NULL;
|
||||
if (result)
|
||||
free (last_errstring);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* These functions are called by dlerror_run... */
|
||||
|
||||
struct do_dlopen_args
|
||||
{
|
||||
/* Argument to do_dlopen. */
|
||||
const char *name;
|
||||
|
||||
/* Return from do_dlopen. */
|
||||
struct link_map *map;
|
||||
};
|
||||
|
||||
struct do_dlsym_args
|
||||
{
|
||||
/* Arguments to do_dlsym. */
|
||||
struct link_map *map;
|
||||
const char *name;
|
||||
|
||||
/* Return values of do_dlsym. */
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref;
|
||||
};
|
||||
|
||||
static void
|
||||
do_dlopen (void *ptr)
|
||||
{
|
||||
struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
|
||||
/* Open and relocate the shared object. */
|
||||
args->map = _dl_open (args->name, RTLD_LAZY, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_dlsym (void *ptr)
|
||||
{
|
||||
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
||||
args->ref = NULL;
|
||||
args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
|
||||
args->map->l_local_scope,
|
||||
args->map->l_name, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
do_dlclose (void *ptr)
|
||||
{
|
||||
_dl_close ((struct link_map *) ptr);
|
||||
}
|
||||
|
||||
/* ... and these functions call dlerror_run. */
|
||||
|
||||
void *
|
||||
__libc_dlopen (const char *__name)
|
||||
{
|
||||
struct do_dlopen_args args;
|
||||
args.name = __name;
|
||||
|
||||
return (dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map);
|
||||
}
|
||||
|
||||
void *
|
||||
__libc_dlsym (void *__map, const char *__name)
|
||||
{
|
||||
struct do_dlsym_args args;
|
||||
args.map = __map;
|
||||
args.name = __name;
|
||||
|
||||
return (dlerror_run (do_dlsym, &args) ? NULL
|
||||
: (void *) (args.loadbase + args.ref->st_value));
|
||||
}
|
||||
|
||||
int
|
||||
__libc_dlclose (void *__map)
|
||||
{
|
||||
return dlerror_run (do_dlclose, __map);
|
||||
}
|
@ -127,7 +127,7 @@ dl_open_worker (void *a)
|
||||
/* If the substitution failed don't try to load. */
|
||||
if (*new_file == '\0')
|
||||
_dl_signal_error (0, "dlopen",
|
||||
"empty dynamics string token substitution");
|
||||
"empty dynamic string token substitution");
|
||||
|
||||
/* Now we have a new file name. */
|
||||
file = new_file;
|
||||
|
@ -28,9 +28,10 @@ extern struct link_map *_dl_profile_map;
|
||||
|
||||
|
||||
void
|
||||
_dl_mcount_wrapper (ElfW(Addr) selfpc)
|
||||
_dl_mcount_wrapper (void *selfpc)
|
||||
{
|
||||
_dl_mcount ((ElfW(Addr)) __builtin_return_address (0), selfpc);
|
||||
_dl_mcount ((ElfW(Addr)) __builtin_return_address (0),
|
||||
(ElfW(Addr)) selfpc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -407,7 +407,7 @@ extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc);
|
||||
/* This function is simply a wrapper around the _dl_mcount function
|
||||
which does not require a FROMPC parameter since this is the
|
||||
calling function. */
|
||||
extern void _dl_mcount_wrapper (ElfW(Addr) selfpc);
|
||||
extern void _dl_mcount_wrapper (void *selfpc);
|
||||
|
||||
|
||||
/* Show the members of the auxiliary array passed up from the kernel. */
|
||||
@ -432,7 +432,7 @@ extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform,
|
||||
helps do it. */
|
||||
#define _CALL_DL_FCT(fctp, args) \
|
||||
({ if (_dl_profile_map != NULL) \
|
||||
_dl_mcount_wrapper ((ElfW(Addr)) fctp); \
|
||||
_dl_mcount_wrapper (fctp); \
|
||||
(*fctp) args; \
|
||||
})
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <assert.h>
|
||||
#include <gconv.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
int
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <bits/libc-lock.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <ldsodefs.h>
|
||||
#include <gconv_int.h>
|
||||
|
||||
|
@ -26,10 +26,8 @@
|
||||
#include <bits/libc-lock.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ldsodefs.h>
|
||||
#include <gconv_int.h>
|
||||
|
||||
|
||||
/* This is a tuning parameter. If a transformation module is not used
|
||||
anymore it gets not immediately unloaded. Instead we wait a certain
|
||||
number of load attempts for further modules. If none of the
|
||||
@ -39,13 +37,10 @@
|
||||
before unloading. */
|
||||
#define TRIES_BEFORE_UNLOAD 2
|
||||
|
||||
|
||||
/* Array of loaded objects. This is shared by all threads so we have
|
||||
to use semaphores to access it. */
|
||||
static void *loaded;
|
||||
|
||||
|
||||
|
||||
/* Comparison function for searching `loaded_object' tree. */
|
||||
static int
|
||||
known_compare (const void *p1, const void *p2)
|
||||
@ -58,70 +53,6 @@ known_compare (const void *p1, const void *p2)
|
||||
return (intptr_t) s1->handle - (intptr_t) s2->handle;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_open (void *a)
|
||||
{
|
||||
struct __gconv_loaded_object *args = (struct __gconv_loaded_object *) a;
|
||||
/* Open and relocate the shared object. */
|
||||
args->handle = _dl_open (args->name, RTLD_LAZY, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
internal_function
|
||||
dlerror_run (void (*operate) (void *), void *args)
|
||||
{
|
||||
char *last_errstring = NULL;
|
||||
int result;
|
||||
|
||||
(void) _dl_catch_error (&last_errstring, operate, args);
|
||||
|
||||
result = last_errstring != NULL;
|
||||
if (result)
|
||||
free (last_errstring);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct get_sym_args
|
||||
{
|
||||
/* Arguments to get_sym. */
|
||||
struct link_map *map;
|
||||
const char *name;
|
||||
|
||||
/* Return values of get_sym. */
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref;
|
||||
};
|
||||
|
||||
static void
|
||||
get_sym (void *a)
|
||||
{
|
||||
struct get_sym_args *args = (struct get_sym_args *) a;
|
||||
args->ref = NULL;
|
||||
args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
|
||||
args->map->l_local_scope,
|
||||
args->map->l_name, 0);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
internal_function
|
||||
__gconv_find_func (void *handle, const char *name)
|
||||
{
|
||||
struct get_sym_args args;
|
||||
|
||||
args.map = handle;
|
||||
args.name = name;
|
||||
|
||||
return (dlerror_run (get_sym, &args) ? NULL
|
||||
: (void *) (args.loadbase + args.ref->st_value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Open the gconv database if necessary. A non-negative return value
|
||||
means success. */
|
||||
struct __gconv_loaded_object *
|
||||
@ -170,9 +101,10 @@ __gconv_find_shlib (const char *name)
|
||||
{
|
||||
if (found->counter < -TRIES_BEFORE_UNLOAD)
|
||||
{
|
||||
if (dlerror_run (do_open, found) == 0)
|
||||
found->handle = __libc_dlopen (found->name);
|
||||
if (found->handle != NULL)
|
||||
{
|
||||
found->fct = __gconv_find_func (found->handle, "gconv");
|
||||
found->fct = __libc_dlsym (found->handle, "gconv");
|
||||
if (found->fct == NULL)
|
||||
{
|
||||
/* Argh, no conversion function. There is something
|
||||
@ -182,10 +114,8 @@ __gconv_find_shlib (const char *name)
|
||||
}
|
||||
else
|
||||
{
|
||||
found->init_fct = __gconv_find_func (found->handle,
|
||||
"gconv_init");
|
||||
found->end_fct = __gconv_find_func (found->handle,
|
||||
"gconv_end");
|
||||
found->init_fct = __libc_dlsym (found->handle, "gconv_init");
|
||||
found->end_fct = __libc_dlsym (found->handle, "gconv_end");
|
||||
|
||||
/* We have succeeded in loading the shared object. */
|
||||
found->counter = 1;
|
||||
@ -224,11 +154,8 @@ do_release_shlib (const void *nodep, VISIT value, int level)
|
||||
{
|
||||
if (--obj->counter < -TRIES_BEFORE_UNLOAD && obj->handle != NULL)
|
||||
{
|
||||
/* Unload the shared object. We don't use the trick to
|
||||
catch errors since in the case an error is signalled
|
||||
something is really wrong. */
|
||||
_dl_close (obj->handle);
|
||||
|
||||
/* Unload the shared object. */
|
||||
__libc_dlclose (obj->handle);
|
||||
obj->handle = NULL;
|
||||
}
|
||||
}
|
||||
@ -258,11 +185,9 @@ do_release_all (void *nodep)
|
||||
{
|
||||
struct __gconv_loaded_object *obj = (struct __gconv_loaded_object *) nodep;
|
||||
|
||||
/* Unload the shared object. We don't use the trick to
|
||||
catch errors since in the case an error is signalled
|
||||
something is really wrong. */
|
||||
/* Unload the shared object. */
|
||||
if (obj->handle != NULL)
|
||||
_dl_close (obj->handle);
|
||||
__libc_dlclose (obj->handle);
|
||||
|
||||
free (obj);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ struct __gconv_loaded_object
|
||||
int counter;
|
||||
|
||||
/* The handle for the shared object. */
|
||||
struct link_map *handle;
|
||||
void *handle;
|
||||
|
||||
/* Pointer to the functions the module defines. */
|
||||
__gconv_fct fct;
|
||||
@ -135,10 +135,6 @@ extern int __gconv_close_transform (struct __gconv_step *__steps,
|
||||
extern struct __gconv_loaded_object *__gconv_find_shlib (const char *__name)
|
||||
internal_function;
|
||||
|
||||
/* Find function named NAME in shared object referenced by HANDLE. */
|
||||
void *__gconv_find_func (void *handle, const char *name)
|
||||
internal_function;
|
||||
|
||||
/* Release shared object. If no further reference is available unload
|
||||
the object. */
|
||||
extern int __gconv_release_shlib (struct __gconv_loaded_object *__handle)
|
||||
|
@ -4,4 +4,11 @@
|
||||
/* Now define the internal interfaces. */
|
||||
extern void *__dlvsym __P ((void *__handle, __const char *__name,
|
||||
__const char *__version));
|
||||
|
||||
extern void *__libc_dlopen __P ((__const char *__name));
|
||||
extern void *__libc_dlsym __P ((void *__map, __const char *__name));
|
||||
extern int __libc_dlclose __P ((void *__map));
|
||||
extern int _dl_addr __P ((const void *address, Dl_info *info))
|
||||
internal_function;
|
||||
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <bits/libc-lock.h>
|
||||
#endif
|
||||
|
||||
#include <ldsodefs.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ldsodefs.h> /* We need some help from ld.so. */
|
||||
|
||||
#if !defined DO_STATIC_NSS || defined PIC
|
||||
# include <gnu/lib-names.h>
|
||||
@ -245,60 +244,6 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
|
||||
}
|
||||
|
||||
|
||||
#if !defined DO_STATIC_NSS || defined PIC
|
||||
static int
|
||||
nss_dlerror_run (void (*operate) (void *), void *args)
|
||||
{
|
||||
char *last_errstring = NULL;
|
||||
int result;
|
||||
|
||||
(void) _dl_catch_error (&last_errstring, operate, args);
|
||||
|
||||
result = last_errstring != NULL;
|
||||
if (result)
|
||||
free (last_errstring);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct do_open_args
|
||||
{
|
||||
/* Argument to do_open. */
|
||||
char *shlib_name;
|
||||
service_user *ni;
|
||||
};
|
||||
|
||||
struct get_sym_args
|
||||
{
|
||||
/* Arguments to get_sym. */
|
||||
struct link_map *map;
|
||||
char *name;
|
||||
|
||||
/* Return values of get_sym. */
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref;
|
||||
};
|
||||
|
||||
static void
|
||||
do_open (void *a)
|
||||
{
|
||||
struct do_open_args *args = (struct do_open_args *) a;
|
||||
/* Open and relocate the shared object. */
|
||||
args->ni->library->lib_handle = _dl_open (args->shlib_name, RTLD_LAZY, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
get_sym (void *a)
|
||||
{
|
||||
struct get_sym_args *args = (struct get_sym_args *) a;
|
||||
args->ref = NULL;
|
||||
args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
|
||||
args->map->l_local_scope,
|
||||
args->map->l_name, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Comparison function for searching NI->known tree. */
|
||||
static int
|
||||
known_compare (const void *p1, const void *p2)
|
||||
@ -376,18 +321,17 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
|
||||
size_t shlen = (7 + strlen (ni->library->name) + 3
|
||||
+ strlen (__nss_shlib_revision) + 1);
|
||||
int saved_errno = errno;
|
||||
struct do_open_args args;
|
||||
args.shlib_name = __alloca (shlen);
|
||||
args.ni = ni;
|
||||
char shlib_name[shlen];
|
||||
|
||||
/* Construct shared object name. */
|
||||
__stpcpy (__stpcpy (__stpcpy (__stpcpy (args.shlib_name,
|
||||
__stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
|
||||
"libnss_"),
|
||||
ni->library->name),
|
||||
".so"),
|
||||
__nss_shlib_revision);
|
||||
|
||||
if (nss_dlerror_run (do_open, &args) != 0)
|
||||
ni->library->lib_handle = __libc_dlopen (shlib_name);
|
||||
if (ni->library->lib_handle == NULL)
|
||||
{
|
||||
/* Failed to load the library. */
|
||||
ni->library->lib_handle = (void *) -1l;
|
||||
@ -400,22 +344,19 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
|
||||
result = NULL;
|
||||
else
|
||||
{
|
||||
/* Get the desired function. Again, GNU ld.so magic ahead. */
|
||||
/* Get the desired function. */
|
||||
size_t namlen = (5 + strlen (ni->library->name) + 1
|
||||
+ strlen (fct_name) + 1);
|
||||
struct get_sym_args args;
|
||||
args.name = __alloca (namlen);
|
||||
args.map = ni->library->lib_handle;
|
||||
char name[namlen];
|
||||
|
||||
/* Construct the function name. */
|
||||
__stpcpy (__stpcpy (__stpcpy (__stpcpy (args.name, "_nss_"),
|
||||
__stpcpy (__stpcpy (__stpcpy (__stpcpy (name, "_nss_"),
|
||||
ni->library->name),
|
||||
"_"),
|
||||
fct_name);
|
||||
|
||||
/* Look up the symbol. */
|
||||
result = (nss_dlerror_run (get_sym, &args) ? NULL
|
||||
: (void *) (args.loadbase + args.ref->st_value));
|
||||
result = __libc_dlsym (ni->library->lib_handle, name);
|
||||
}
|
||||
#else
|
||||
/* We can't get function address dynamically in static linking. */
|
||||
@ -796,7 +737,7 @@ free_mem (void)
|
||||
{
|
||||
service_library *oldl = library;
|
||||
|
||||
_dl_close (library->lib_handle);
|
||||
__libc_dlclose (library->lib_handle);
|
||||
|
||||
library = library->next;
|
||||
free (oldl);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Implementation of gamma function according to ISO C.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -34,11 +34,15 @@ __ieee754_gamma_r (double x, int *signgamp)
|
||||
EXTRACT_WORDS (hx, lx, x);
|
||||
|
||||
if (((hx & 0x7fffffff) | lx) == 0)
|
||||
/* Return value for x == 0 is NaN with invalid exception. */
|
||||
return x / x;
|
||||
{
|
||||
/* Return value for x == 0 is NaN with invalid exception. */
|
||||
*signgamp = 0;
|
||||
return x / x;
|
||||
}
|
||||
if (hx < 0 && (u_int32_t) hx < 0xfff00000 && __rint (x) == x)
|
||||
{
|
||||
/* Return value for integer x < 0 is NaN with invalid exception. */
|
||||
*signgamp = 0;
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Implementation of gamma function according to ISO C.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -33,11 +33,15 @@ __ieee754_gammaf_r (float x, int *signgamp)
|
||||
GET_FLOAT_WORD (hx, x);
|
||||
|
||||
if ((hx & 0x7fffffff) == 0)
|
||||
/* Return value for x == 0 is NaN with invalid exception. */
|
||||
return x / x;
|
||||
{
|
||||
/* Return value for x == 0 is NaN with invalid exception. */
|
||||
*signgamp = 0;
|
||||
return x / x;
|
||||
}
|
||||
if (hx < 0 && (u_int32_t) hx < 0xff800000 && __rintf (x) == x)
|
||||
{
|
||||
/* Return value for integer x < 0 is NaN with invalid exception. */
|
||||
*signgamp = 0;
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Implementation of gamma function according to ISO C.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -33,11 +33,15 @@ __ieee754_gammal_r (long double x, int *signgamp)
|
||||
GET_LDOUBLE_WORDS (es, hx, lx, x);
|
||||
|
||||
if (((es & 0x7fff) | hx | lx) == 0)
|
||||
/* Return value for x == 0 is NaN with invalid exception. */
|
||||
return x / x;
|
||||
{
|
||||
/* Return value for x == 0 is NaN with invalid exception. */
|
||||
*signgamp = 0;
|
||||
return x / x;
|
||||
}
|
||||
if ((hx & 0x8000) != 0 && (hx & 0x7fff) != 0x7fff && __rintl (x) == x)
|
||||
{
|
||||
/* Return value for integer x < 0 is NaN with invalid exception. */
|
||||
*signgamp = 0;
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user