mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
Update.
1997-07-26 04:14 Ulrich Drepper <drepper@cygnus.com> * elf/Makefile (distribute): Add genrtldtbl.awk. (before-compile): Add rtldtbl.h. (GAWK): New variable. (generated): Add trusted-dirs.h and rtldtbl.h. ($(objpfx)rtldtbl.h): New rule. File is needed by dl-load.c. * elf/dl-load.c: Rewrite. Now use cache and look for shared objects in machine dependent directories. * elf/dl-object.c (_dl_new_object): Initialize l_rpath_dirs member. * elf/dl-support.c: Rename function to non_dynamic_init and add initialization for _dl_platform, _dl_platformlen, _dl_pagesize and call to initializer for search path. * elf/elf.h: Add AT_PLATFORM and AT_HWCAP. * elf/genrtldtbl.awk: New file. * elf/link.h: Add type definitions and declarations for search path cache. * elf/rtld.c: Add definitions of variables used for search path cache. * sysdeps/generic/dl-sysdep.c: Let auxiliary vector initialize _dl_platform. Initialize _dl_pagesize early and use this value. * sysdeps/i386/dl-machine.h: Add code for _dl_platform handling. * sysdeps/mach/hurd/dl-sysdep.c: Initialize _dl_pagesize. * sysdeps/unix/sysv/linux/dl-sysdep.c: Use _dl_pagesize instead of calling getpagesize. * elf/dl-error.c (_dl_signal_error): Make message nicer. * nss/libnss_files.map: Fix typo. Reported by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>. * sysdeps/generic/strsep.c: Optimize case where separator set contains only one character. * sysdeps/libm-ieee754/s_ccosh.c: Correct sign of result for real == +-Inf. * sysdeps/libm-ieee754/s_ccoshf.c: Likewise. * sysdeps/libm-ieee754/s_ccoshl.c: Likewise. 1997-07-25 09:15 H.J. Lu <hjl@gnu.ai.mit.edu> * sysdeps/sparc/udiv_qrnnd.S: Check PIC instead of __PIC__. * sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S: Likewise. * sysdeps/unix/mips/sysdep.S: Likewise. * sysdeps/unix/sysv/linux/mips/clone.S: Likewise. * sysdeps/mips/bsd-_setjmp.S: Remove __PIC__ comment. * sysdeps/mips/bsd-setjmp.S: Likewise. * sysdeps/mips/dl-machine.h: Remove extra stuff. * sysdeps/mips/mips64/dl-machine.h: Likewise. 1997-07-25 18:55 Philip Blundell <Philip.Blundell@pobox.com> * sysdeps/standalone/arm/sysdep.c: New file. 1997-07-25 13:25 Philip Blundell <Philip.Blundell@pobox.com> * aout/Makefile: New file. * Makeconfig (binfmt-subdir): Assume a.out when not ELF. * sysdeps/generic/machine-gmon.h: Add warning about limitations of __builtin_return_address(). * sysdeps/arm/machine-gmon.h: New file, use assembly to avoid above problem. 1997-07-25 16:24 H.J. Lu <hjl@gnu.ai.mit.edu> * elf/dl-deps.c (_dl_map_object_deps): Fix a typo. 1997-07-22 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * math/libm-test.c (ccos_test, ccosh_test): Fix sign in some tests. 1997-07-24 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sunrpc/clnt_udp.c (clntudp_call): Rename cu_wait from timeout to not shadow the variable in the outer scope.
This commit is contained in:
parent
1522c3682c
commit
0a54e4010f
79
ChangeLog
79
ChangeLog
@ -1,3 +1,82 @@
|
|||||||
|
1997-07-26 04:14 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* elf/Makefile (distribute): Add genrtldtbl.awk.
|
||||||
|
(before-compile): Add rtldtbl.h.
|
||||||
|
(GAWK): New variable.
|
||||||
|
(generated): Add trusted-dirs.h and rtldtbl.h.
|
||||||
|
($(objpfx)rtldtbl.h): New rule. File is needed by dl-load.c.
|
||||||
|
* elf/dl-load.c: Rewrite. Now use cache and look for shared
|
||||||
|
objects in machine dependent directories.
|
||||||
|
* elf/dl-object.c (_dl_new_object): Initialize l_rpath_dirs member.
|
||||||
|
* elf/dl-support.c: Rename function to non_dynamic_init and add
|
||||||
|
initialization for _dl_platform, _dl_platformlen, _dl_pagesize
|
||||||
|
and call to initializer for search path.
|
||||||
|
* elf/elf.h: Add AT_PLATFORM and AT_HWCAP.
|
||||||
|
* elf/genrtldtbl.awk: New file.
|
||||||
|
* elf/link.h: Add type definitions and declarations for search
|
||||||
|
path cache.
|
||||||
|
* elf/rtld.c: Add definitions of variables used for search path cache.
|
||||||
|
* sysdeps/generic/dl-sysdep.c: Let auxiliary vector initialize
|
||||||
|
_dl_platform. Initialize _dl_pagesize early and use this value.
|
||||||
|
* sysdeps/i386/dl-machine.h: Add code for _dl_platform handling.
|
||||||
|
* sysdeps/mach/hurd/dl-sysdep.c: Initialize _dl_pagesize.
|
||||||
|
* sysdeps/unix/sysv/linux/dl-sysdep.c: Use _dl_pagesize instead
|
||||||
|
of calling getpagesize.
|
||||||
|
|
||||||
|
* elf/dl-error.c (_dl_signal_error): Make message nicer.
|
||||||
|
|
||||||
|
* nss/libnss_files.map: Fix typo.
|
||||||
|
Reported by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>.
|
||||||
|
|
||||||
|
* sysdeps/generic/strsep.c: Optimize case where separator set contains
|
||||||
|
only one character.
|
||||||
|
|
||||||
|
* sysdeps/libm-ieee754/s_ccosh.c: Correct sign of result for real
|
||||||
|
== +-Inf.
|
||||||
|
* sysdeps/libm-ieee754/s_ccoshf.c: Likewise.
|
||||||
|
* sysdeps/libm-ieee754/s_ccoshl.c: Likewise.
|
||||||
|
|
||||||
|
1997-07-25 09:15 H.J. Lu <hjl@gnu.ai.mit.edu>
|
||||||
|
|
||||||
|
* sysdeps/sparc/udiv_qrnnd.S: Check PIC instead of __PIC__.
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S: Likewise.
|
||||||
|
* sysdeps/unix/mips/sysdep.S: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/mips/clone.S: Likewise.
|
||||||
|
|
||||||
|
* sysdeps/mips/bsd-_setjmp.S: Remove __PIC__ comment.
|
||||||
|
* sysdeps/mips/bsd-setjmp.S: Likewise.
|
||||||
|
|
||||||
|
* sysdeps/mips/dl-machine.h: Remove extra stuff.
|
||||||
|
* sysdeps/mips/mips64/dl-machine.h: Likewise.
|
||||||
|
|
||||||
|
1997-07-25 18:55 Philip Blundell <Philip.Blundell@pobox.com>
|
||||||
|
|
||||||
|
* sysdeps/standalone/arm/sysdep.c: New file.
|
||||||
|
|
||||||
|
1997-07-25 13:25 Philip Blundell <Philip.Blundell@pobox.com>
|
||||||
|
|
||||||
|
* aout/Makefile: New file.
|
||||||
|
* Makeconfig (binfmt-subdir): Assume a.out when not ELF.
|
||||||
|
|
||||||
|
* sysdeps/generic/machine-gmon.h: Add warning about limitations of
|
||||||
|
__builtin_return_address().
|
||||||
|
* sysdeps/arm/machine-gmon.h: New file, use assembly to avoid
|
||||||
|
above problem.
|
||||||
|
|
||||||
|
1997-07-25 16:24 H.J. Lu <hjl@gnu.ai.mit.edu>
|
||||||
|
|
||||||
|
* elf/dl-deps.c (_dl_map_object_deps): Fix a typo.
|
||||||
|
|
||||||
|
1997-07-22 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||||
|
|
||||||
|
* math/libm-test.c (ccos_test, ccosh_test): Fix sign in some
|
||||||
|
tests.
|
||||||
|
|
||||||
|
1997-07-24 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||||
|
|
||||||
|
* sunrpc/clnt_udp.c (clntudp_call): Rename cu_wait from timeout to
|
||||||
|
not shadow the variable in the outer scope.
|
||||||
|
|
||||||
1997-07-24 03:14 Ulrich Drepper <drepper@cygnus.com>
|
1997-07-24 03:14 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* elf/dl-deps.c: Complete rewrite to handle DT_AUXILIARY correctly.
|
* elf/dl-deps.c: Complete rewrite to handle DT_AUXILIARY correctly.
|
||||||
|
@ -88,7 +88,8 @@ include $(common-objpfx)config.make
|
|||||||
ifeq ($(elf),yes)
|
ifeq ($(elf),yes)
|
||||||
binfmt-subdir = elf
|
binfmt-subdir = elf
|
||||||
else
|
else
|
||||||
binfmt-subdir =
|
# This is probably better than nothing.
|
||||||
|
binfmt-subdir = aout
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Complete path to sysdep dirs.
|
# Complete path to sysdep dirs.
|
||||||
|
@ -302,7 +302,9 @@ init_hash(hashp, file, info)
|
|||||||
if (file != NULL) {
|
if (file != NULL) {
|
||||||
if (stat(file, &statbuf))
|
if (stat(file, &statbuf))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
#if defined _STATBUF_ST_BLKSIZE
|
||||||
hashp->BSIZE = statbuf.st_blksize;
|
hashp->BSIZE = statbuf.st_blksize;
|
||||||
|
#endif
|
||||||
hashp->BSHIFT = __hash_log2(hashp->BSIZE);
|
hashp->BSHIFT = __hash_log2(hashp->BSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
elf/Makefile
13
elf/Makefile
@ -35,15 +35,18 @@ elide-routines.so = $(dl-routines) dl-support enbl-secure
|
|||||||
# interpreter and operating independent of libc.
|
# interpreter and operating independent of libc.
|
||||||
rtld-routines := rtld $(dl-routines) dl-sysdep dl-minimal
|
rtld-routines := rtld $(dl-routines) dl-sysdep dl-minimal
|
||||||
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
||||||
dl-hash.h soinit.c sofini.c ldd.sh.in ldd.bash.in eval.c
|
dl-hash.h soinit.c sofini.c ldd.sh.in ldd.bash.in eval.c \
|
||||||
|
genrtldtbl.awk
|
||||||
|
|
||||||
extra-libs = libdl
|
extra-libs = libdl
|
||||||
extra-libs-others = $(extra-libs)
|
extra-libs-others = $(extra-libs)
|
||||||
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr
|
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr
|
||||||
libdl-map := libdl.map
|
libdl-map := libdl.map
|
||||||
|
|
||||||
before-compile = $(objpfx)trusted-dirs.h
|
before-compile = $(objpfx)trusted-dirs.h $(objpfx)rtldtbl.h
|
||||||
|
|
||||||
|
# We need GNU awk for the genrtldtbl.awk script.
|
||||||
|
GAWK = gawk
|
||||||
|
|
||||||
all: # Make this the default target; it will be defined in Rules.
|
all: # Make this the default target; it will be defined in Rules.
|
||||||
|
|
||||||
@ -51,7 +54,7 @@ include ../Makeconfig
|
|||||||
|
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
extra-objs = $(rtld-routines:=.so) soinit.so sofini.so eval.so
|
extra-objs = $(rtld-routines:=.so) soinit.so sofini.so eval.so
|
||||||
generated = librtld.so dl-allobjs.so
|
generated = librtld.so dl-allobjs.so trusted-dirs.h rtldtbl.h
|
||||||
install-others = $(inst_slibdir)/$(rtld-installed-name)
|
install-others = $(inst_slibdir)/$(rtld-installed-name)
|
||||||
install-bin = ldd
|
install-bin = ldd
|
||||||
endif
|
endif
|
||||||
@ -143,6 +146,10 @@ $(objpfx)trusted-dirs.h: Makefile
|
|||||||
echo " \"$$dir\","; \
|
echo " \"$$dir\","; \
|
||||||
done;) > $@T
|
done;) > $@T
|
||||||
mv -f $@T $@
|
mv -f $@T $@
|
||||||
|
$(objpfx)rtldtbl.h: Makefile
|
||||||
|
$(make-target-directory)
|
||||||
|
echo "$(default-rpath)" | $(GAWK) -f genrtldtbl.awk > $@T
|
||||||
|
mv -f $@T $@
|
||||||
CPPFLAGS-dl-load.c = -I$(objdir)/$(subdir)
|
CPPFLAGS-dl-load.c = -I$(objdir)/$(subdir)
|
||||||
CFLAGS-dl-load.c += -Wno-uninitialized
|
CFLAGS-dl-load.c += -Wno-uninitialized
|
||||||
|
|
||||||
|
@ -57,12 +57,9 @@ openaux (void *a)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* We use a very special kind of list to track the three kinds paths
|
/* We use a very special kind of list to track the two kinds paths
|
||||||
through the list of loaded shared objects. We have to
|
through the list of loaded shared objects. We have to
|
||||||
|
|
||||||
- go through all objects in the correct order, which includes the
|
|
||||||
possible recursive loading of auxiliary objects and dependencies
|
|
||||||
|
|
||||||
- produce a flat list with unique members of all involved objects
|
- produce a flat list with unique members of all involved objects
|
||||||
|
|
||||||
- produce a flat list of all shared objects.
|
- produce a flat list of all shared objects.
|
||||||
@ -141,7 +138,7 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
{
|
{
|
||||||
struct link_map *l = runp->map;
|
struct link_map *l = runp->map;
|
||||||
|
|
||||||
if (runp->done == 0 && (l->l_info[AUXTAG] || l->l_info[DT_NEEDED]))
|
if (l->l_info[AUXTAG] || l->l_info[DT_NEEDED])
|
||||||
{
|
{
|
||||||
const char *strtab = ((void *) l->l_addr
|
const char *strtab = ((void *) l->l_addr
|
||||||
+ l->l_info[DT_STRTAB]->d_un.d_ptr);
|
+ l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||||
@ -371,6 +368,6 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
"cannot allocate symbol search list");
|
"cannot allocate symbol search list");
|
||||||
|
|
||||||
for (nlist = 0, runp = head; runp; runp = runp->dup)
|
for (nlist = 0, runp = head; runp; runp = runp->dup)
|
||||||
map->l_searchlist[nlist++] = runp->map;
|
map->l_dupsearchlist[nlist++] = runp->map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ _dl_signal_error (int errcode,
|
|||||||
/* Lossage while resolving the program's own symbols is always fatal. */
|
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||||
extern char **_dl_argv; /* Set in rtld.c at startup. */
|
extern char **_dl_argv; /* Set in rtld.c at startup. */
|
||||||
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
|
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
|
||||||
": error in loading shared libraries\n",
|
": error in loading shared libraries",
|
||||||
objname ?: "", objname ? ": " : "",
|
objname ?: "", objname ? ": " : "",
|
||||||
errstring, errcode ? ": " : "",
|
errstring, errcode ? ": " : "",
|
||||||
errcode ? strerror (errcode) : "", "\n", NULL);
|
errcode ? strerror (errcode) : "", "\n", NULL);
|
||||||
|
481
elf/dl-load.c
481
elf/dl-load.c
@ -1,4 +1,4 @@
|
|||||||
/* _dl_map_object -- Map in a shared object's segments from the file.
|
/* Map in a shared object's segments from the file.
|
||||||
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -17,14 +17,15 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include <link.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <link.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include "dynamic-link.h"
|
#include "dynamic-link.h"
|
||||||
|
|
||||||
|
|
||||||
@ -90,6 +91,8 @@ ELF_PREFERRED_ADDRESS_DATA;
|
|||||||
|
|
||||||
size_t _dl_pagesize;
|
size_t _dl_pagesize;
|
||||||
|
|
||||||
|
extern const char *_dl_platform;
|
||||||
|
extern size_t _dl_platformlen;
|
||||||
|
|
||||||
/* Local version of `strdup' function. */
|
/* Local version of `strdup' function. */
|
||||||
static inline char *
|
static inline char *
|
||||||
@ -105,6 +108,292 @@ local_strdup (const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Implement cache for search path lookup. */
|
||||||
|
#if 0
|
||||||
|
/* This is how generated should look like. I'll remove this once I'm
|
||||||
|
sure everything works correctly. */
|
||||||
|
static struct r_search_path_elem rtld_search_dir1 =
|
||||||
|
{ "/lib/", 5, unknown, 0, unknown, NULL };
|
||||||
|
static struct r_search_path_elem rtld_search_dir2 =
|
||||||
|
{ "/usr/lib/", 9, unknown, 0, unknown, &r ld_search_dir1 };
|
||||||
|
|
||||||
|
static struct r_search_path_elem *rtld_search_dirs[] =
|
||||||
|
{
|
||||||
|
&rtld_search_dir1,
|
||||||
|
&rtld_search_dir2,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct r_search_path_elem *all_dirs = &rtld_search_dir2;
|
||||||
|
#else
|
||||||
|
# include "rtldtbl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static size_t max_dirnamelen;
|
||||||
|
|
||||||
|
static inline struct r_search_path_elem **
|
||||||
|
fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
|
||||||
|
const char **trusted)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
size_t nelems = 0;
|
||||||
|
|
||||||
|
while ((cp = __strsep (&rpath, sep)) != NULL)
|
||||||
|
{
|
||||||
|
struct r_search_path_elem *dirp;
|
||||||
|
size_t len = strlen (cp);
|
||||||
|
/* Remove trailing slashes. */
|
||||||
|
while (len > 1 && cp[len - 1] == '/')
|
||||||
|
--len;
|
||||||
|
|
||||||
|
/* Make sure we don't use untrusted directories if we run SUID. */
|
||||||
|
if (trusted != NULL)
|
||||||
|
{
|
||||||
|
const char **trun = trusted;
|
||||||
|
|
||||||
|
/* All trusted directory must be complete name. */
|
||||||
|
if (cp[0] != '/')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while (*trun != NULL
|
||||||
|
&& (memcmp (*trun, cp, len) != 0 || (*trun)[len] != '\0'))
|
||||||
|
++trun;
|
||||||
|
|
||||||
|
if (*trun == NULL)
|
||||||
|
/* It's no trusted directory, skip it. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now add one. */
|
||||||
|
if (len > 0)
|
||||||
|
cp[len++] = '/';
|
||||||
|
|
||||||
|
/* See if this directory is already known. */
|
||||||
|
for (dirp = all_dirs; dirp != NULL; dirp = dirp->next)
|
||||||
|
if (dirp->dirnamelen == len && strcmp (cp, dirp->dirname) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (dirp != NULL)
|
||||||
|
{
|
||||||
|
/* It is available, see whether it's in our own list. */
|
||||||
|
size_t cnt;
|
||||||
|
for (cnt = 0; cnt < nelems; ++cnt)
|
||||||
|
if (result[cnt] == dirp)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (cnt == nelems)
|
||||||
|
result[nelems++] = dirp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It's a new directory. Create an entry and add it. */
|
||||||
|
dirp = (struct r_search_path_elem *) malloc (sizeof (*dirp));
|
||||||
|
if (dirp == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
|
"cannot create cache for search path");
|
||||||
|
|
||||||
|
dirp->dirnamelen = len;
|
||||||
|
dirp->dirstatus = unknown;
|
||||||
|
|
||||||
|
/* Add the name of the machine dependent directory if a machine
|
||||||
|
is defined. */
|
||||||
|
if (_dl_platform != NULL)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
dirp->machdirnamelen = len + _dl_platformlen + 1;
|
||||||
|
tmp = (char *) malloc (len + _dl_platformlen + 2);
|
||||||
|
if (tmp == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
|
"cannot create cache for search path");
|
||||||
|
memcpy (tmp, cp, len);
|
||||||
|
memcpy (tmp + len, _dl_platform, _dl_platformlen);
|
||||||
|
tmp[len + _dl_platformlen] = '/';
|
||||||
|
tmp[len + _dl_platformlen + 1] = '\0';
|
||||||
|
|
||||||
|
dirp->dirname = tmp;
|
||||||
|
dirp->machdirstatus = unknown;
|
||||||
|
|
||||||
|
if (max_dirnamelen < dirp->machdirnamelen)
|
||||||
|
max_dirnamelen = dirp->machdirnamelen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
dirp->machdirnamelen = len;
|
||||||
|
dirp->machdirstatus = nonexisting;
|
||||||
|
|
||||||
|
tmp = (char *) malloc (len + 1);
|
||||||
|
if (tmp == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
|
"cannot create cache for search path");
|
||||||
|
memcpy (tmp, cp, len);
|
||||||
|
tmp[len] = '\0';
|
||||||
|
|
||||||
|
if (max_dirnamelen < dirp->dirnamelen)
|
||||||
|
max_dirnamelen = dirp->dirnamelen;
|
||||||
|
|
||||||
|
dirp->dirname = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirp->next = all_dirs;
|
||||||
|
all_dirs = dirp;
|
||||||
|
|
||||||
|
/* Put it in the result array. */
|
||||||
|
result[nelems++] = dirp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the array. */
|
||||||
|
result[nelems] = NULL;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct r_search_path_elem **
|
||||||
|
decompose_rpath (const char *rpath, size_t additional_room)
|
||||||
|
{
|
||||||
|
/* Make a copy we can work with. */
|
||||||
|
char *copy = strdupa (rpath);
|
||||||
|
char *cp;
|
||||||
|
struct r_search_path_elem **result;
|
||||||
|
/* First count the number of necessary elements in the result array. */
|
||||||
|
size_t nelems = 0;
|
||||||
|
|
||||||
|
for (cp = copy; *cp != '\0'; ++cp)
|
||||||
|
if (*cp == ':')
|
||||||
|
++nelems;
|
||||||
|
|
||||||
|
/* Allocate room for the result. NELEMS + 1 + ADDITIONAL_ROOM is an upper
|
||||||
|
limit for the number of necessary entries. */
|
||||||
|
result = (struct r_search_path_elem **) malloc ((nelems + 1
|
||||||
|
+ additional_room + 1)
|
||||||
|
* sizeof (*result));
|
||||||
|
if (result == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
|
||||||
|
|
||||||
|
return fillin_rpath (copy, result, ":", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_init_paths (void)
|
||||||
|
{
|
||||||
|
struct r_search_path_elem **pelem;
|
||||||
|
|
||||||
|
/* We have in `search_path' the information about the RPATH of the
|
||||||
|
dynamic loader. Now fill in the information about the applications
|
||||||
|
RPATH and the directories addressed by the LD_LIBRARY_PATH environment
|
||||||
|
variable. */
|
||||||
|
struct link_map *l;
|
||||||
|
|
||||||
|
/* First determine how many elements the LD_LIBRARY_PATH contents has. */
|
||||||
|
const char *llp = getenv ("LD_LIBRARY_PATH");
|
||||||
|
size_t nllp;
|
||||||
|
|
||||||
|
if (llp != NULL && *llp != '\0')
|
||||||
|
{
|
||||||
|
/* Simply count the number of colons. */
|
||||||
|
const char *cp = llp;
|
||||||
|
nllp = 1;
|
||||||
|
while (*cp)
|
||||||
|
if (*cp++ == ':')
|
||||||
|
++nllp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nllp = 0;
|
||||||
|
|
||||||
|
l = _dl_loaded;
|
||||||
|
if (l && l->l_type != lt_loaded && l->l_info[DT_RPATH])
|
||||||
|
{
|
||||||
|
/* Allocate room for the search path and fill in information from
|
||||||
|
RPATH. */
|
||||||
|
l->l_rpath_dirs =
|
||||||
|
decompose_rpath ((const char *) (l->l_addr
|
||||||
|
+ l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
|
+ l->l_info[DT_RPATH]->d_un.d_val),
|
||||||
|
nllp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If we have no LD_LIBRARY_PATH and no RPATH we must tell this
|
||||||
|
somehow to prevent we look this up again and again. */
|
||||||
|
if (nllp == 0)
|
||||||
|
l->l_rpath_dirs = (struct r_search_path_elem **) -1l;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l->l_rpath_dirs =
|
||||||
|
(struct r_search_path_elem **) malloc ((nllp + 1)
|
||||||
|
* sizeof (*l->l_rpath_dirs));
|
||||||
|
if (l->l_rpath_dirs == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
|
"cannot create cache for search path");
|
||||||
|
l->l_rpath_dirs[0] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nllp > 0)
|
||||||
|
{
|
||||||
|
static const char *trusted_dirs[] =
|
||||||
|
{
|
||||||
|
#include "trusted-dirs.h"
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
char *copy = strdupa (llp);
|
||||||
|
|
||||||
|
/* Decompose the LD_LIBRARY_PATH and fill in the result.
|
||||||
|
First search for the next place to enter elements. */
|
||||||
|
struct r_search_path_elem **result = l->l_rpath_dirs;
|
||||||
|
while (*result != NULL)
|
||||||
|
++result;
|
||||||
|
|
||||||
|
/* We need to take care that the LD_LIBRARY_PATH environement
|
||||||
|
variable can contain a semicolon. */
|
||||||
|
(void) fillin_rpath (copy, result, ":;",
|
||||||
|
__libc_enable_secure ? trusted_dirs : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set up the rest of the rtld_search_dirs. */
|
||||||
|
for (pelem = rtld_search_dirs; *pelem != NULL; ++pelem)
|
||||||
|
{
|
||||||
|
struct r_search_path_elem *relem = *pelem;
|
||||||
|
|
||||||
|
if (_dl_platform != NULL)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
relem->machdirnamelen = relem->dirnamelen + _dl_platformlen + 1;
|
||||||
|
tmp = (char *) malloc (relem->machdirnamelen + 1);
|
||||||
|
if (tmp == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
|
"cannot create cache for search path");
|
||||||
|
|
||||||
|
memcpy (tmp, relem->dirname, relem->dirnamelen);
|
||||||
|
memcpy (tmp + relem->dirnamelen, _dl_platform, _dl_platformlen);
|
||||||
|
tmp[relem->dirnamelen + _dl_platformlen] = '/';
|
||||||
|
tmp[relem->dirnamelen + _dl_platformlen + 1] = '\0';
|
||||||
|
|
||||||
|
relem->dirname = tmp;
|
||||||
|
|
||||||
|
relem->machdirstatus = unknown;
|
||||||
|
|
||||||
|
if (max_dirnamelen < relem->machdirnamelen)
|
||||||
|
max_dirnamelen = relem->machdirnamelen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
relem->machdirnamelen = relem->dirnamelen;
|
||||||
|
relem->machdirstatus = nonexisting;
|
||||||
|
|
||||||
|
if (max_dirnamelen < relem->dirnamelen)
|
||||||
|
max_dirnamelen = relem->dirnamelen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Map in the shared object NAME, actually located in REALNAME, and already
|
/* Map in the shared object NAME, actually located in REALNAME, and already
|
||||||
opened on FD. */
|
opened on FD. */
|
||||||
|
|
||||||
@ -131,7 +420,7 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
|||||||
l->l_next->l_prev = l->l_prev;
|
l->l_next->l_prev = l->l_prev;
|
||||||
free (l);
|
free (l);
|
||||||
}
|
}
|
||||||
free (name);
|
free (name); /* XXX Can this be correct? --drepper */
|
||||||
free (realname);
|
free (realname);
|
||||||
_dl_signal_error (code, name, msg);
|
_dl_signal_error (code, name, msg);
|
||||||
}
|
}
|
||||||
@ -207,9 +496,6 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dl_pagesize == 0)
|
|
||||||
_dl_pagesize = __getpagesize ();
|
|
||||||
|
|
||||||
/* Map in the first page to read the header. */
|
/* Map in the first page to read the header. */
|
||||||
header = map (0, sizeof *header);
|
header = map (0, sizeof *header);
|
||||||
|
|
||||||
@ -458,83 +744,87 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to open NAME in one of the directories in DIRPATH.
|
/* Try to open NAME in one of the directories in DIRS.
|
||||||
Return the fd, or -1. If successful, fill in *REALNAME
|
Return the fd, or -1. If successful, fill in *REALNAME
|
||||||
with the malloc'd full directory name. */
|
with the malloc'd full directory name. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
open_path (const char *name, size_t namelen,
|
open_path (const char *name, size_t namelen,
|
||||||
const char *dirpath,
|
struct r_search_path_elem **dirs,
|
||||||
char **realname,
|
char **realname)
|
||||||
const char *trusted_dirs[])
|
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
const char *p;
|
int fd = -1;
|
||||||
int fd;
|
|
||||||
|
|
||||||
p = dirpath;
|
if (dirs == NULL || *dirs == NULL)
|
||||||
if (p == NULL || *p == '\0')
|
|
||||||
{
|
{
|
||||||
__set_errno (ENOENT);
|
__set_errno (ENOENT);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = __alloca (strlen (dirpath) + 1 + namelen);
|
buf = __alloca (max_dirnamelen + namelen);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
size_t buflen;
|
struct r_search_path_elem *this_dir = *dirs;
|
||||||
size_t this_len;
|
size_t buflen = 0;
|
||||||
|
|
||||||
dirpath = p;
|
if (this_dir->machdirstatus != nonexisting)
|
||||||
p = strpbrk (dirpath, ":;");
|
|
||||||
if (p == NULL)
|
|
||||||
p = strchr (dirpath, '\0');
|
|
||||||
|
|
||||||
this_len = p - dirpath;
|
|
||||||
|
|
||||||
/* When we run a setuid program we do not accept any directory. */
|
|
||||||
if (__libc_enable_secure)
|
|
||||||
{
|
|
||||||
/* All trusted directory must be complete name. */
|
|
||||||
if (dirpath[0] != '/')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If we got a list of trusted directories only accept one
|
|
||||||
of these. */
|
|
||||||
if (trusted_dirs != NULL)
|
|
||||||
{
|
|
||||||
const char **trust = trusted_dirs;
|
|
||||||
|
|
||||||
while (*trust != NULL)
|
|
||||||
if (memcmp (dirpath, *trust, this_len) == 0
|
|
||||||
&& (*trust)[this_len] == '\0')
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
++trust;
|
|
||||||
|
|
||||||
/* If directory is not trusted, ignore this directory. */
|
|
||||||
if (*trust == NULL)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this_len == 0)
|
|
||||||
{
|
|
||||||
/* Two adjacent colons, or a colon at the beginning or the end of
|
|
||||||
the path means to search the current directory. */
|
|
||||||
(void) memcpy (buf, name, namelen);
|
|
||||||
buflen = namelen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Construct the pathname to try. */
|
/* Construct the pathname to try. */
|
||||||
(void) memcpy (buf, dirpath, this_len);
|
(void) memcpy (buf, this_dir->dirname, this_dir->machdirnamelen);
|
||||||
buf[this_len] = '/';
|
(void) memcpy (buf + this_dir->machdirnamelen, name, namelen);
|
||||||
(void) memcpy (&buf[this_len + 1], name, namelen);
|
buflen = this_dir->machdirnamelen + namelen;
|
||||||
buflen = this_len + 1 + namelen;
|
|
||||||
|
fd = __open (buf, O_RDONLY);
|
||||||
|
if (this_dir->machdirstatus == unknown)
|
||||||
|
if (fd != -1)
|
||||||
|
this_dir->machdirstatus = existing;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We failed to open machine dependent library. Let's
|
||||||
|
test whether there is any directory at all. */
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
buf[this_dir->machdirnamelen - 1] = '\0';
|
||||||
|
|
||||||
|
if (stat (buf, &st) != 0 || ! S_ISDIR (st.st_mode))
|
||||||
|
/* The directory does not exist ot it is no directory. */
|
||||||
|
this_dir->machdirstatus = nonexisting;
|
||||||
|
else
|
||||||
|
this_dir->machdirstatus = existing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == -1 && this_dir->dirstatus != nonexisting)
|
||||||
|
{
|
||||||
|
/* Construct the pathname to try. */
|
||||||
|
(void) memcpy (buf, this_dir->dirname, this_dir->dirnamelen);
|
||||||
|
(void) memcpy (buf + this_dir->dirnamelen, name, namelen);
|
||||||
|
buflen = this_dir->dirnamelen + namelen;
|
||||||
|
|
||||||
|
fd = __open (buf, O_RDONLY);
|
||||||
|
if (this_dir->dirstatus == unknown)
|
||||||
|
if (fd != -1)
|
||||||
|
this_dir->dirstatus = existing;
|
||||||
|
else
|
||||||
|
/* We failed to open library. Let's test whether there
|
||||||
|
is any directory at all. */
|
||||||
|
if (this_dir->dirnamelen <= 1)
|
||||||
|
this_dir->dirstatus = existing;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
buf[this_dir->dirnamelen - 1] = '\0';
|
||||||
|
|
||||||
|
if (stat (buf, &st) != 0 || ! S_ISDIR (st.st_mode))
|
||||||
|
/* The directory does not exist ot it is no directory. */
|
||||||
|
this_dir->dirstatus = nonexisting;
|
||||||
|
else
|
||||||
|
this_dir->dirstatus = existing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = __open (buf, O_RDONLY);
|
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
*realname = malloc (buflen);
|
*realname = malloc (buflen);
|
||||||
@ -555,7 +845,7 @@ open_path (const char *name, size_t namelen,
|
|||||||
/* The file exists and is readable, but something went wrong. */
|
/* The file exists and is readable, but something went wrong. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while (*p++ != '\0');
|
while (*++dirs != NULL);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -593,39 +883,34 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
|
|||||||
|
|
||||||
size_t namelen = strlen (name) + 1;
|
size_t namelen = strlen (name) + 1;
|
||||||
|
|
||||||
inline void trypath (const char *dirpath, const char *trusted[])
|
|
||||||
{
|
|
||||||
fd = open_path (name, namelen, dirpath, &realname, trusted);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
/* First try the DT_RPATH of the dependent object that caused NAME
|
/* First try the DT_RPATH of the dependent object that caused NAME
|
||||||
to be loaded. Then that object's dependent, and on up. */
|
to be loaded. Then that object's dependent, and on up. */
|
||||||
for (l = loader; fd == -1 && l; l = l->l_loader)
|
for (l = loader; fd == -1 && l; l = l->l_loader)
|
||||||
if (l && l->l_info[DT_RPATH])
|
if (l && l->l_info[DT_RPATH])
|
||||||
trypath ((const char *) (l->l_addr +
|
|
||||||
l->l_info[DT_STRTAB]->d_un.d_ptr +
|
|
||||||
l->l_info[DT_RPATH]->d_un.d_val), NULL);
|
|
||||||
/* If dynamically linked, try the DT_RPATH of the executable itself. */
|
|
||||||
l = _dl_loaded;
|
|
||||||
if (fd == -1 && l && l->l_type != lt_loaded && l->l_info[DT_RPATH])
|
|
||||||
trypath ((const char *) (l->l_addr +
|
|
||||||
l->l_info[DT_STRTAB]->d_un.d_ptr +
|
|
||||||
l->l_info[DT_RPATH]->d_un.d_val), NULL);
|
|
||||||
/* Try an environment variable (unless setuid). */
|
|
||||||
if (fd == -1)
|
|
||||||
{
|
|
||||||
static const char *trusted_dirs[] =
|
|
||||||
{
|
{
|
||||||
#include "trusted-dirs.h"
|
/* Make sure the cache information is available. */
|
||||||
NULL
|
if (l->l_rpath_dirs == NULL)
|
||||||
};
|
{
|
||||||
const char *ld_library_path = getenv ("LD_LIBRARY_PATH");
|
size_t ptrval = (l->l_addr
|
||||||
|
+ l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
|
+ l->l_info[DT_RPATH]->d_un.d_val);
|
||||||
|
l->l_rpath_dirs =
|
||||||
|
decompose_rpath ((const char *) ptrval, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
|
||||||
|
fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If dynamically linked, try the DT_RPATH of the executable itself
|
||||||
|
and the LD_LIBRARY_PATH environment variable. */
|
||||||
|
l = _dl_loaded;
|
||||||
|
if (fd == -1 && l && l->l_type != lt_loaded
|
||||||
|
&& l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
|
||||||
|
fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
|
||||||
|
|
||||||
if (ld_library_path != NULL && *ld_library_path != '\0')
|
|
||||||
trypath (ld_library_path, trusted_dirs);
|
|
||||||
}
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
/* Check the list of libraries in the file /etc/ld.so.cache,
|
/* Check the list of libraries in the file /etc/ld.so.cache,
|
||||||
@ -646,12 +931,10 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, try the default path. */
|
/* Finally, try the default path. */
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
fd = open_path (name, namelen, rtld_search_dirs, &realname);
|
||||||
extern const char *_dl_rpath; /* Set in rtld.c. */
|
|
||||||
trypath (_dl_rpath, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ _dl_new_object (char *realname, const char *libname, int type)
|
|||||||
newname->next = NULL;
|
newname->next = NULL;
|
||||||
new->l_libname = newname;
|
new->l_libname = newname;
|
||||||
new->l_type = type;
|
new->l_type = type;
|
||||||
|
new->l_rpath_dirs = NULL;
|
||||||
|
|
||||||
if (_dl_loaded == NULL)
|
if (_dl_loaded == NULL)
|
||||||
{
|
{
|
||||||
|
@ -20,8 +20,10 @@
|
|||||||
/* This file defines some things that for the dynamic linker are defined in
|
/* This file defines some things that for the dynamic linker are defined in
|
||||||
rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
|
rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
|
||||||
|
|
||||||
|
#include <link.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dl-machine.h>
|
||||||
|
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
char **_dl_argv = &__progname; /* This is checked for some error messages. */
|
char **_dl_argv = &__progname; /* This is checked for some error messages. */
|
||||||
@ -30,15 +32,36 @@ char **_dl_argv = &__progname; /* This is checked for some error messages. */
|
|||||||
For the dynamic linker it is set by -rpath when linking. */
|
For the dynamic linker it is set by -rpath when linking. */
|
||||||
const char *_dl_rpath = DEFAULT_RPATH;
|
const char *_dl_rpath = DEFAULT_RPATH;
|
||||||
|
|
||||||
|
/* Name of the architecture. */
|
||||||
|
const char *_dl_platform;
|
||||||
|
size_t _dl_platformlen;
|
||||||
|
|
||||||
/* If nonzero print warnings about problematic situations. */
|
/* If nonzero print warnings about problematic situations. */
|
||||||
int _dl_verbose;
|
int _dl_verbose;
|
||||||
|
|
||||||
|
/* Structure to store information about search paths. */
|
||||||
|
struct r_search_path *_dl_search_paths;
|
||||||
|
|
||||||
static void init_verbose (void) __attribute__ ((unused));
|
|
||||||
|
static void non_dynamic_init (void) __attribute__ ((unused));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_verbose (void)
|
non_dynamic_init (void)
|
||||||
{
|
{
|
||||||
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
|
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
|
||||||
|
|
||||||
|
/* Initialize the data structures for the search paths for shared
|
||||||
|
objects. */
|
||||||
|
_dl_init_paths ();
|
||||||
|
|
||||||
|
#ifdef DL_PLATFORM_INIT
|
||||||
|
DL_PLATFORM_INIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Now determine the length of the platform string. */
|
||||||
|
if (_dl_platform != NULL)
|
||||||
|
_dl_platformlen = strlen (_dl_platform);
|
||||||
|
|
||||||
|
_dl_pagesize = __getpagesize ();
|
||||||
}
|
}
|
||||||
text_set_element (__libc_subinit, init_verbose);
|
text_set_element (__libc_subinit, non_dynamic_init);
|
||||||
|
@ -654,6 +654,11 @@ typedef struct
|
|||||||
#define AT_GID 13 /* Real gid */
|
#define AT_GID 13 /* Real gid */
|
||||||
#define AT_EGID 14 /* Effective gid */
|
#define AT_EGID 14 /* Effective gid */
|
||||||
|
|
||||||
|
/* Some more special a_type values describing the hardware. */
|
||||||
|
#define AT_PLATFORM 15 /* String identifying platform. */
|
||||||
|
#define AT_HWCAP 16 /* Machine dependent hints about
|
||||||
|
processor capabilities. */
|
||||||
|
|
||||||
/* Motorola 68k specific definitions. */
|
/* Motorola 68k specific definitions. */
|
||||||
|
|
||||||
/* m68k relocs. */
|
/* m68k relocs. */
|
||||||
|
28
elf/genrtldtbl.awk
Normal file
28
elf/genrtldtbl.awk
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#! /usr/bin/awk
|
||||||
|
BEGIN {
|
||||||
|
FS=":";
|
||||||
|
count=0;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
for (i = 1; i <= NF; ++i) {
|
||||||
|
dir[count++] = gensub(/((.*)[^/])?[/]*/, "\\1", "", $i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
printf ("static struct r_search_path_elem rtld_search_dir%d =\n", i+1);
|
||||||
|
printf (" { \"%s/\", %d, unknown, 0, unknown, ",
|
||||||
|
dir[i], length (dir[i]) + 1);
|
||||||
|
if (i== 0)
|
||||||
|
printf ("NULL };\n");
|
||||||
|
else
|
||||||
|
printf ("&rtld_search_dir%d };\n", i);
|
||||||
|
}
|
||||||
|
printf ("\nstatic struct r_search_path_elem *rtld_search_dirs[] =\n{\n");
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
printf (" &rtld_search_dir%d,\n", i + 1);
|
||||||
|
}
|
||||||
|
printf (" NULL\n};\n\n");
|
||||||
|
printf ("static struct r_search_path_elem *all_dirs = &rtld_search_dir%d;\n",
|
||||||
|
count);
|
||||||
|
}
|
26
elf/link.h
26
elf/link.h
@ -91,6 +91,25 @@ struct r_found_version
|
|||||||
const char *filename;
|
const char *filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* We want to cache information about the searches for shared objects. */
|
||||||
|
|
||||||
|
enum r_dir_status { unknown, nonexisting, existing };
|
||||||
|
|
||||||
|
struct r_search_path_elem
|
||||||
|
{
|
||||||
|
const char *dirname;
|
||||||
|
|
||||||
|
size_t dirnamelen;
|
||||||
|
enum r_dir_status dirstatus;
|
||||||
|
|
||||||
|
size_t machdirnamelen;
|
||||||
|
enum r_dir_status machdirstatus;
|
||||||
|
|
||||||
|
/* This link is only used in the `all_dirs' member of `r_search_path'. */
|
||||||
|
struct r_search_path_elem *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
|
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
|
||||||
members form a chain of all the shared objects loaded at startup.
|
members form a chain of all the shared objects loaded at startup.
|
||||||
|
|
||||||
@ -163,6 +182,9 @@ struct link_map
|
|||||||
/* Array with version names. */
|
/* Array with version names. */
|
||||||
unsigned int l_nversions;
|
unsigned int l_nversions;
|
||||||
struct r_found_version *l_versions;
|
struct r_found_version *l_versions;
|
||||||
|
|
||||||
|
/* Collected information about own RPATH directories. */
|
||||||
|
struct r_search_path_elem **l_rpath_dirs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -407,6 +429,10 @@ extern void _dl_debug_state (void);
|
|||||||
in the `r_ldbase' member. Returns the address of the structure. */
|
in the `r_ldbase' member. Returns the address of the structure. */
|
||||||
extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase);
|
extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase);
|
||||||
|
|
||||||
|
/* Initialize the basic data structure for the search paths. */
|
||||||
|
void _dl_init_paths (void);
|
||||||
|
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif /* link.h */
|
#endif /* link.h */
|
||||||
|
@ -58,6 +58,9 @@ int _dl_argc;
|
|||||||
char **_dl_argv;
|
char **_dl_argv;
|
||||||
const char *_dl_rpath;
|
const char *_dl_rpath;
|
||||||
int _dl_verbose;
|
int _dl_verbose;
|
||||||
|
const char *_dl_platform;
|
||||||
|
size_t _dl_platformlen;
|
||||||
|
struct r_search_path *_dl_search_paths;
|
||||||
|
|
||||||
/* Set nonzero during loading and initialization of executable and
|
/* Set nonzero during loading and initialization of executable and
|
||||||
libraries, cleared before the executable's entry point runs. This
|
libraries, cleared before the executable's entry point runs. This
|
||||||
@ -526,6 +529,10 @@ of this helper program; chances are you did not intend to run this program.\n",
|
|||||||
assert (i == npreloads);
|
assert (i == npreloads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the data structures for the search paths for shared
|
||||||
|
objects. */
|
||||||
|
_dl_init_paths ();
|
||||||
|
|
||||||
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
||||||
specified some libraries to load, these are inserted before the actual
|
specified some libraries to load, these are inserted before the actual
|
||||||
dependencies in the executable's searchlist for symbol resolution. */
|
dependencies in the executable's searchlist for symbol resolution. */
|
||||||
|
@ -2907,10 +2907,10 @@ ccos_test (void)
|
|||||||
|
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (0.0, 0.0));
|
result = FUNC(ccos) (BUILD_COMPLEX (0.0, 0.0));
|
||||||
check ("real(ccos(0 + 0i)) = 1.0", __real__ result, 1.0);
|
check ("real(ccos(0 + 0i)) = 1.0", __real__ result, 1.0);
|
||||||
check ("imag(ccos(0 + 0i)) = 0", __imag__ result, 0);
|
check ("imag(ccos(0 + 0i)) = -0", __imag__ result, minus_zero);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (minus_zero, 0.0));
|
result = FUNC(ccos) (BUILD_COMPLEX (minus_zero, 0.0));
|
||||||
check ("real(ccos(-0 + 0i)) = 1.0", __real__ result, 1.0);
|
check ("real(ccos(-0 + 0i)) = 1.0", __real__ result, 1.0);
|
||||||
check ("imag(ccos(-0 + 0i)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccos(-0 + 0i)) = 0", __imag__ result, 0.0);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (0.0, minus_zero));
|
result = FUNC(ccos) (BUILD_COMPLEX (0.0, minus_zero));
|
||||||
check ("real(ccos(0 - 0i)) = 1.0", __real__ result, 1.0);
|
check ("real(ccos(0 - 0i)) = 1.0", __real__ result, 1.0);
|
||||||
check ("imag(ccos(0 - 0i)) = 0", __imag__ result, 0.0);
|
check ("imag(ccos(0 - 0i)) = 0", __imag__ result, 0.0);
|
||||||
@ -2941,13 +2941,13 @@ ccos_test (void)
|
|||||||
|
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (0.0, plus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (0.0, plus_infty));
|
||||||
check_isinfp ("real(ccos(0 + i Inf)) = +Inf", __real__ result);
|
check_isinfp ("real(ccos(0 + i Inf)) = +Inf", __real__ result);
|
||||||
check ("imag(ccos(0 + i Inf)) = 0", __imag__ result, 0);
|
check ("imag(ccos(0 + i Inf)) = -0", __imag__ result, minus_zero);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (0.0, minus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (0.0, minus_infty));
|
||||||
check_isinfp ("real(ccos(0 - i Inf)) = +Inf", __real__ result);
|
check_isinfp ("real(ccos(0 - i Inf)) = +Inf", __real__ result);
|
||||||
check ("imag(ccos(0 - i Inf)) = 0", __imag__ result, 0);
|
check ("imag(ccos(0 - i Inf)) = 0", __imag__ result, 0);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (minus_zero, plus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (minus_zero, plus_infty));
|
||||||
check_isinfp ("real(ccos(-0 + i Inf)) = +Inf", __real__ result);
|
check_isinfp ("real(ccos(-0 + i Inf)) = +Inf", __real__ result);
|
||||||
check ("imag(ccos(-0 + i Inf)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccos(-0 + i Inf)) = 0", __imag__ result, 0.0);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (minus_zero, minus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (minus_zero, minus_infty));
|
||||||
check_isinfp ("real(ccos(-0 - i Inf)) = +Inf", __real__ result);
|
check_isinfp ("real(ccos(-0 - i Inf)) = +Inf", __real__ result);
|
||||||
check ("imag(ccos(-0 - i Inf)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccos(-0 - i Inf)) = -0", __imag__ result, minus_zero);
|
||||||
@ -2975,13 +2975,13 @@ ccos_test (void)
|
|||||||
|
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (4.625, plus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (4.625, plus_infty));
|
||||||
check_isinfn ("real(ccos(4.625 + i Inf)) = -Inf", __real__ result);
|
check_isinfn ("real(ccos(4.625 + i Inf)) = -Inf", __real__ result);
|
||||||
check_isinfn ("imag(ccos(4.625 + i Inf)) = -Inf", __imag__ result);
|
check_isinfp ("imag(ccos(4.625 + i Inf)) = +Inf", __imag__ result);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (4.625, minus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (4.625, minus_infty));
|
||||||
check_isinfn ("real(ccos(4.625 - i Inf)) = -Inf", __real__ result);
|
check_isinfn ("real(ccos(4.625 - i Inf)) = -Inf", __real__ result);
|
||||||
check_isinfn ("imag(ccos(4.625 - i Inf)) = -Inf", __imag__ result);
|
check_isinfn ("imag(ccos(4.625 - i Inf)) = -Inf", __imag__ result);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (-4.625, plus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (-4.625, plus_infty));
|
||||||
check_isinfn ("real(ccos(-4.625 + i Inf)) = -Inf", __real__ result);
|
check_isinfn ("real(ccos(-4.625 + i Inf)) = -Inf", __real__ result);
|
||||||
check_isinfp ("imag(ccos(-4.625 + i Inf)) = +Inf", __imag__ result);
|
check_isinfn ("imag(ccos(-4.625 + i Inf)) = -Inf", __imag__ result);
|
||||||
result = FUNC(ccos) (BUILD_COMPLEX (-4.625, minus_infty));
|
result = FUNC(ccos) (BUILD_COMPLEX (-4.625, minus_infty));
|
||||||
check_isinfn ("real(ccos(-4.625 - i Inf)) = -Inf", __real__ result);
|
check_isinfn ("real(ccos(-4.625 - i Inf)) = -Inf", __real__ result);
|
||||||
check_isinfp ("imag(ccos(-4.625 - i Inf)) = +Inf", __imag__ result);
|
check_isinfp ("imag(ccos(-4.625 - i Inf)) = +Inf", __imag__ result);
|
||||||
@ -3077,13 +3077,13 @@ ccosh_test (void)
|
|||||||
check ("imag(ccosh(0 + 0i)) = 0", __imag__ result, 0);
|
check ("imag(ccosh(0 + 0i)) = 0", __imag__ result, 0);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (minus_zero, 0.0));
|
result = FUNC(ccosh) (BUILD_COMPLEX (minus_zero, 0.0));
|
||||||
check ("real(ccosh(-0 + 0i)) = 1.0", __real__ result, 1.0);
|
check ("real(ccosh(-0 + 0i)) = 1.0", __real__ result, 1.0);
|
||||||
check ("imag(ccosh(-0 + 0i)) = 0", __imag__ result, 0);
|
check ("imag(ccosh(-0 + 0i)) = -0", __imag__ result, minus_zero);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (0.0, minus_zero));
|
result = FUNC(ccosh) (BUILD_COMPLEX (0.0, minus_zero));
|
||||||
check ("real(ccosh(0 - 0i)) = 1.0", __real__ result, 1.0);
|
check ("real(ccosh(0 - 0i)) = 1.0", __real__ result, 1.0);
|
||||||
check ("imag(ccosh(0 - 0i)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccosh(0 - 0i)) = -0", __imag__ result, minus_zero);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (minus_zero, minus_zero));
|
result = FUNC(ccosh) (BUILD_COMPLEX (minus_zero, minus_zero));
|
||||||
check ("real(ccosh(-0 - 0i)) = 1.0", __real__ result, 1.0);
|
check ("real(ccosh(-0 - 0i)) = 1.0", __real__ result, 1.0);
|
||||||
check ("imag(ccosh(-0 - 0i)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccosh(-0 - 0i)) = 0", __imag__ result, 0.0);
|
||||||
|
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (0.0, plus_infty));
|
result = FUNC(ccosh) (BUILD_COMPLEX (0.0, plus_infty));
|
||||||
check_isnan_exc ("real(ccosh(0 + i Inf)) = NaN plus invalid exception",
|
check_isnan_exc ("real(ccosh(0 + i Inf)) = NaN plus invalid exception",
|
||||||
@ -3111,13 +3111,13 @@ ccosh_test (void)
|
|||||||
check ("imag(ccosh(+Inf + 0i)) = 0", __imag__ result, 0);
|
check ("imag(ccosh(+Inf + 0i)) = 0", __imag__ result, 0);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 0.0));
|
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 0.0));
|
||||||
check_isinfp ("real(ccosh(-Inf + 0i)) = +Inf", __real__ result);
|
check_isinfp ("real(ccosh(-Inf + 0i)) = +Inf", __real__ result);
|
||||||
check ("imag(ccosh(-Inf + 0i)) = 0", __imag__ result, 0);
|
check ("imag(ccosh(-Inf + 0i)) = -0", __imag__ result, minus_zero);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (plus_infty, minus_zero));
|
result = FUNC(ccosh) (BUILD_COMPLEX (plus_infty, minus_zero));
|
||||||
check_isinfp ("real(ccosh(+Inf - 0i)) = +Inf", __real__ result);
|
check_isinfp ("real(ccosh(+Inf - 0i)) = +Inf", __real__ result);
|
||||||
check ("imag(ccosh(+Inf - 0i)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccosh(+Inf - 0i)) = -0", __imag__ result, minus_zero);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, minus_zero));
|
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, minus_zero));
|
||||||
check_isinfp ("real(ccosh(-Inf - 0i)) = +Inf", __real__ result);
|
check_isinfp ("real(ccosh(-Inf - 0i)) = +Inf", __real__ result);
|
||||||
check ("imag(ccosh(-Inf - 0i)) = -0", __imag__ result, minus_zero);
|
check ("imag(ccosh(-Inf - 0i)) = 0", __imag__ result, 0.0);
|
||||||
|
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (plus_infty, plus_infty));
|
result = FUNC(ccosh) (BUILD_COMPLEX (plus_infty, plus_infty));
|
||||||
check_isinfp_exc ("real(ccosh(+Inf + i Inf)) = +Inf plus invalid exception",
|
check_isinfp_exc ("real(ccosh(+Inf + i Inf)) = +Inf plus invalid exception",
|
||||||
@ -3145,13 +3145,13 @@ ccosh_test (void)
|
|||||||
check_isinfn ("imag(ccosh(+Inf + i4.625)) = -Inf", __imag__ result);
|
check_isinfn ("imag(ccosh(+Inf + i4.625)) = -Inf", __imag__ result);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 4.625));
|
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 4.625));
|
||||||
check_isinfn ("real(ccosh(-Inf + i4.625)) = -Inf", __real__ result);
|
check_isinfn ("real(ccosh(-Inf + i4.625)) = -Inf", __real__ result);
|
||||||
check_isinfn ("imag(ccosh(-Inf + i4.625)) = -Inf", __imag__ result);
|
check_isinfp ("imag(ccosh(-Inf + i4.625)) = Inf", __imag__ result);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (plus_infty, -4.625));
|
result = FUNC(ccosh) (BUILD_COMPLEX (plus_infty, -4.625));
|
||||||
check_isinfn ("real(ccosh(+Inf - i4.625)) = -Inf", __real__ result);
|
check_isinfn ("real(ccosh(+Inf - i4.625)) = -Inf", __real__ result);
|
||||||
check_isinfp ("imag(ccosh(+Inf - i4.625)) = +Inf", __imag__ result);
|
check_isinfp ("imag(ccosh(+Inf - i4.625)) = +Inf", __imag__ result);
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, -4.625));
|
result = FUNC(ccosh) (BUILD_COMPLEX (minus_infty, -4.625));
|
||||||
check_isinfn ("real(ccosh(-Inf - i4.625)) = -Inf", __real__ result);
|
check_isinfn ("real(ccosh(-Inf - i4.625)) = -Inf", __real__ result);
|
||||||
check_isinfp ("imag(ccosh(-Inf - i4.625)) = +Inf", __imag__ result);
|
check_isinfn ("imag(ccosh(-Inf - i4.625)) = -Inf", __imag__ result);
|
||||||
|
|
||||||
result = FUNC(ccosh) (BUILD_COMPLEX (6.75, plus_infty));
|
result = FUNC(ccosh) (BUILD_COMPLEX (6.75, plus_infty));
|
||||||
check_isnan_exc ("real(ccosh(6.75 + i Inf)) = NaN plus invalid exception",
|
check_isnan_exc ("real(ccosh(6.75 + i Inf)) = NaN plus invalid exception",
|
||||||
|
@ -22,7 +22,7 @@ GLIBC_2.0 {
|
|||||||
_nss_files_setgrent; _nss_files_sethostent; _nss_files_setnetent;
|
_nss_files_setgrent; _nss_files_sethostent; _nss_files_setnetent;
|
||||||
_nss_files_setnetgrent; _nss_files_setprotoent; _nss_files_setpwent;
|
_nss_files_setnetgrent; _nss_files_setprotoent; _nss_files_setpwent;
|
||||||
_nss_files_setrpcent; _nss_files_setservent; _nss_files_setspent;
|
_nss_files_setrpcent; _nss_files_setservent; _nss_files_setspent;
|
||||||
__nss_netgroup_parseline;
|
_nss_netgroup_parseline;
|
||||||
|
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
|
@ -309,10 +309,10 @@ send_again:
|
|||||||
#endif /* def FD_SETSIZE */
|
#endif /* def FD_SETSIZE */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
struct timeval timeout = cu->cu_wait;
|
struct timeval cu_wait = cu->cu_wait;
|
||||||
readfds = mask;
|
readfds = mask;
|
||||||
switch (select (_rpc_dtablesize (), &readfds, (fd_set*) NULL,
|
switch (select (_rpc_dtablesize (), &readfds, (fd_set*) NULL,
|
||||||
(fd_set*) NULL, &timeout))
|
(fd_set*) NULL, &cu_wait))
|
||||||
{
|
{
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
|
55
sysdeps/arm/machine-gmon.h
Normal file
55
sysdeps/arm/machine-gmon.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* Machine-dependent definitions for profiling support. ARM version.
|
||||||
|
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/* GCC for the ARM cannot compile __builtin_return_address(N) for N != 0,
|
||||||
|
so we must use an assembly stub. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
#ifndef NO_UNDERSCORES
|
||||||
|
/* The asm symbols for C functions are `_function'.
|
||||||
|
The canonical name for the counter function is `mcount', no _. */
|
||||||
|
void _mcount (void) asm ("mcount");
|
||||||
|
#else
|
||||||
|
/* The canonical name for the function is `_mcount' in both C and asm,
|
||||||
|
but some old asm code might assume it's `mcount'. */
|
||||||
|
void _mcount (void);
|
||||||
|
weak_alias (_mcount, mcount)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void mcount_internal (u_long frompc, u_long selfpc);
|
||||||
|
|
||||||
|
#define _MCOUNT_DECL(frompc, selfpc) \
|
||||||
|
static void mcount_internal (u_long frompc, u_long selfpc)
|
||||||
|
|
||||||
|
#define MCOUNT \
|
||||||
|
void _mcount (void) \
|
||||||
|
{ \
|
||||||
|
register unsigned long int frompc, selfpc; \
|
||||||
|
__asm__("movs fp, fp; " \
|
||||||
|
"moveq %0, $0; " \
|
||||||
|
"ldrne %0, [fp, $-4]; " \
|
||||||
|
"ldrne %1, [fp, $-12]; " \
|
||||||
|
"movnes %1, %1; " \
|
||||||
|
"ldrne %1, [%1, $-4]; " \
|
||||||
|
: "=g" (selfpc), "=g" (frompc) \
|
||||||
|
: : "cc" \
|
||||||
|
); \
|
||||||
|
if (selfpc) \
|
||||||
|
mcount_internal(frompc, selfpc); \
|
||||||
|
}
|
@ -26,11 +26,14 @@
|
|||||||
#include <link.h>
|
#include <link.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <dl-machine.h>
|
||||||
|
|
||||||
extern int _dl_argc;
|
extern int _dl_argc;
|
||||||
extern char **_dl_argv;
|
extern char **_dl_argv;
|
||||||
extern char **_environ;
|
extern char **_environ;
|
||||||
extern size_t _dl_pagesize;
|
extern size_t _dl_pagesize;
|
||||||
|
extern const char *_dl_platform;
|
||||||
|
extern size_t _dl_platformlen;
|
||||||
extern void _end;
|
extern void _end;
|
||||||
extern void ENTRY_POINT (void);
|
extern void ENTRY_POINT (void);
|
||||||
|
|
||||||
@ -57,6 +60,7 @@ _dl_sysdep_start (void **start_argptr,
|
|||||||
_dl_argc = *(long *) start_argptr;
|
_dl_argc = *(long *) start_argptr;
|
||||||
_dl_argv = (char **) start_argptr + 1;
|
_dl_argv = (char **) start_argptr + 1;
|
||||||
_environ = &_dl_argv[_dl_argc + 1];
|
_environ = &_dl_argv[_dl_argc + 1];
|
||||||
|
_dl_platform = NULL; /* Default to nothing known about the platform. */
|
||||||
start_argptr = (void **) _environ;
|
start_argptr = (void **) _environ;
|
||||||
while (*start_argptr)
|
while (*start_argptr)
|
||||||
++start_argptr;
|
++start_argptr;
|
||||||
@ -93,6 +97,12 @@ _dl_sysdep_start (void **start_argptr,
|
|||||||
case AT_EGID:
|
case AT_EGID:
|
||||||
egid = av->a_un.a_val;
|
egid = av->a_un.a_val;
|
||||||
break;
|
break;
|
||||||
|
case AT_PLATFORM:
|
||||||
|
_dl_platform = av->a_un.a_ptr;
|
||||||
|
break;
|
||||||
|
case AT_HWCAP:
|
||||||
|
/* Well, what shall we use? A string or an integer with bits? */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linux doesn't provide us with any of these values on the stack
|
/* Linux doesn't provide us with any of these values on the stack
|
||||||
@ -107,21 +117,28 @@ _dl_sysdep_start (void **start_argptr,
|
|||||||
|
|
||||||
__libc_enable_secure = uid != euid || gid != egid;
|
__libc_enable_secure = uid != euid || gid != egid;
|
||||||
|
|
||||||
|
if (_dl_pagesize == 0)
|
||||||
|
_dl_pagesize = __getpagesize ();
|
||||||
|
|
||||||
#ifdef DL_SYSDEP_INIT
|
#ifdef DL_SYSDEP_INIT
|
||||||
DL_SYSDEP_INIT;
|
DL_SYSDEP_INIT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (__sbrk (0) == &_end)
|
#ifdef DL_PLATFORM_INIT
|
||||||
{
|
DL_PLATFORM_INIT;
|
||||||
/* The dynamic linker was run as a program, and so the initial break
|
#endif
|
||||||
starts just after our bss, at &_end. The malloc in dl-minimal.c
|
|
||||||
will consume the rest of this page, so tell the kernel to move the
|
|
||||||
break up that far. When the user program examines its break, it
|
|
||||||
will see this new value and not clobber our data. */
|
|
||||||
size_t pg = __getpagesize ();
|
|
||||||
|
|
||||||
__sbrk (pg - ((&_end - (void *) 0) & (pg - 1)));
|
/* Determine the length of the platform name. */
|
||||||
}
|
if (_dl_platform != NULL)
|
||||||
|
_dl_platformlen = strlen (_dl_platform);
|
||||||
|
|
||||||
|
if (__sbrk (0) == &_end)
|
||||||
|
/* The dynamic linker was run as a program, and so the initial break
|
||||||
|
starts just after our bss, at &_end. The malloc in dl-minimal.c
|
||||||
|
will consume the rest of this page, so tell the kernel to move the
|
||||||
|
break up that far. When the user program examines its break, it
|
||||||
|
will see this new value and not clobber our data. */
|
||||||
|
__sbrk (_dl_pagesize - ((&_end - (void *) 0) & (_dl_pagesize - 1)));
|
||||||
|
|
||||||
(*dl_main) (phdr, phnum, &user_entry);
|
(*dl_main) (phdr, phnum, &user_entry);
|
||||||
return user_entry;
|
return user_entry;
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
void *__builtin_return_address (unsigned int N)
|
void *__builtin_return_address (unsigned int N)
|
||||||
returns the return address of the frame N frames up. */
|
returns the return address of the frame N frames up. */
|
||||||
|
|
||||||
|
/* Be warned that GCC cannot usefully compile __builtin_return_address(N)
|
||||||
|
for N != 0 on all machines. In this case, you may have to write
|
||||||
|
your own version of _mcount(). */
|
||||||
|
|
||||||
#if __GNUC__ < 2
|
#if __GNUC__ < 2
|
||||||
#error "This file uses __builtin_return_address, a GCC 2 extension."
|
#error "This file uses __builtin_return_address, a GCC 2 extension."
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,8 +27,27 @@ __strsep (char **stringp, const char *delim)
|
|||||||
if (! begin || *begin == '\0')
|
if (! begin || *begin == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Find the end of the token. */
|
/* A frequent case is when the delimiter string contains only one
|
||||||
end = strpbrk (begin, delim);
|
character. Here we don't need to call the expensive `strpbrk'
|
||||||
|
function and instead work using `strchr'. */
|
||||||
|
if (delim[0] == '\0' || delim[1] == '\0')
|
||||||
|
{
|
||||||
|
char ch = delim[0];
|
||||||
|
|
||||||
|
if (ch == '\0')
|
||||||
|
end = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (*begin == ch)
|
||||||
|
++begin;
|
||||||
|
|
||||||
|
end = strchr (begin, delim[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Find the end of the token. */
|
||||||
|
end = strpbrk (begin, delim);
|
||||||
|
|
||||||
if (end)
|
if (end)
|
||||||
{
|
{
|
||||||
/* Terminate the token and set *STRINGP past NUL character. */
|
/* Terminate the token and set *STRINGP past NUL character. */
|
||||||
|
@ -44,7 +44,7 @@ elf_machine_matches_host (Elf32_Half e_machine)
|
|||||||
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
|
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
|
||||||
first element of the GOT. This must be inlined in a function which
|
first element of the GOT. This must be inlined in a function which
|
||||||
uses global data. */
|
uses global data. */
|
||||||
static inline Elf32_Addr
|
static inline Elf32_Addr __attribute__ ((unused))
|
||||||
elf_machine_dynamic (void)
|
elf_machine_dynamic (void)
|
||||||
{
|
{
|
||||||
register Elf32_Addr *got asm ("%ebx");
|
register Elf32_Addr *got asm ("%ebx");
|
||||||
@ -86,7 +86,7 @@ static ElfW(Addr) fixup (struct link_map *l, ElfW(Word) reloc_offset)
|
|||||||
/* Set up the loaded object described by L so its unrelocated PLT
|
/* Set up the loaded object described by L so its unrelocated PLT
|
||||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
static inline int
|
static inline int __attribute__ ((unused))
|
||||||
elf_machine_runtime_setup (struct link_map *l, int lazy)
|
elf_machine_runtime_setup (struct link_map *l, int lazy)
|
||||||
{
|
{
|
||||||
Elf32_Addr *got;
|
Elf32_Addr *got;
|
||||||
@ -233,6 +233,23 @@ _dl_start_user:\n\
|
|||||||
/* The i386 never uses Elf32_Rela relocations. */
|
/* The i386 never uses Elf32_Rela relocations. */
|
||||||
#define ELF_MACHINE_NO_RELA 1
|
#define ELF_MACHINE_NO_RELA 1
|
||||||
|
|
||||||
|
/* We define an initialization functions. This is called very early in
|
||||||
|
_dl_sysdep_start. */
|
||||||
|
#define DL_PLATFORM_INIT dl_platform_init ()
|
||||||
|
|
||||||
|
extern const char *_dl_platform;
|
||||||
|
|
||||||
|
static inline void __attribute__ ((unused))
|
||||||
|
dl_platform_init (void)
|
||||||
|
{
|
||||||
|
if (_dl_platform == NULL)
|
||||||
|
/* We default to i386 since all instructions understood by the i386
|
||||||
|
are also understood by later processors. */
|
||||||
|
_dl_platform = "i386";
|
||||||
|
else if (*_dl_platform == '\0')
|
||||||
|
_dl_platform = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !dl_machine_h */
|
#endif /* !dl_machine_h */
|
||||||
|
|
||||||
#ifdef RESOLVE
|
#ifdef RESOLVE
|
||||||
|
@ -32,8 +32,6 @@ __ccosh (__complex__ double x)
|
|||||||
int rcls = fpclassify (__real__ x);
|
int rcls = fpclassify (__real__ x);
|
||||||
int icls = fpclassify (__imag__ x);
|
int icls = fpclassify (__imag__ x);
|
||||||
|
|
||||||
__real__ x = fabs (__real__ x);
|
|
||||||
|
|
||||||
if (rcls >= FP_ZERO)
|
if (rcls >= FP_ZERO)
|
||||||
{
|
{
|
||||||
/* Real part is finite. */
|
/* Real part is finite. */
|
||||||
@ -67,7 +65,7 @@ __ccosh (__complex__ double x)
|
|||||||
{
|
{
|
||||||
/* Imaginary part is 0.0. */
|
/* Imaginary part is 0.0. */
|
||||||
__real__ retval = HUGE_VAL;
|
__real__ retval = HUGE_VAL;
|
||||||
__imag__ retval = __imag__ x;
|
__imag__ retval = __imag__ x * __copysign (1.0, __real__ x);
|
||||||
}
|
}
|
||||||
else if (icls > FP_ZERO)
|
else if (icls > FP_ZERO)
|
||||||
{
|
{
|
||||||
@ -77,7 +75,8 @@ __ccosh (__complex__ double x)
|
|||||||
__sincos (__imag__ x, &sinix, &cosix);
|
__sincos (__imag__ x, &sinix, &cosix);
|
||||||
|
|
||||||
__real__ retval = __copysign (HUGE_VAL, cosix);
|
__real__ retval = __copysign (HUGE_VAL, cosix);
|
||||||
__imag__ retval = __copysign (HUGE_VAL, sinix);
|
__imag__ retval = (__copysign (HUGE_VAL, sinix)
|
||||||
|
* __copysign (1.0, __real__ x));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -32,8 +32,6 @@ __ccoshf (__complex__ float x)
|
|||||||
int rcls = fpclassify (__real__ x);
|
int rcls = fpclassify (__real__ x);
|
||||||
int icls = fpclassify (__imag__ x);
|
int icls = fpclassify (__imag__ x);
|
||||||
|
|
||||||
__real__ x = fabsf (__real__ x);
|
|
||||||
|
|
||||||
if (rcls >= FP_ZERO)
|
if (rcls >= FP_ZERO)
|
||||||
{
|
{
|
||||||
/* Real part is finite. */
|
/* Real part is finite. */
|
||||||
@ -67,7 +65,7 @@ __ccoshf (__complex__ float x)
|
|||||||
{
|
{
|
||||||
/* Imaginary part is 0.0. */
|
/* Imaginary part is 0.0. */
|
||||||
__real__ retval = HUGE_VALF;
|
__real__ retval = HUGE_VALF;
|
||||||
__imag__ retval = __imag__ x;
|
__imag__ retval = __imag__ x * __copysignf (1.0, __real__ x);
|
||||||
}
|
}
|
||||||
else if (icls > FP_ZERO)
|
else if (icls > FP_ZERO)
|
||||||
{
|
{
|
||||||
@ -77,7 +75,8 @@ __ccoshf (__complex__ float x)
|
|||||||
__sincosf (__imag__ x, &sinix, &cosix);
|
__sincosf (__imag__ x, &sinix, &cosix);
|
||||||
|
|
||||||
__real__ retval = __copysignf (HUGE_VALF, cosix);
|
__real__ retval = __copysignf (HUGE_VALF, cosix);
|
||||||
__imag__ retval = __copysignf (HUGE_VALF, sinix);
|
__imag__ retval = (__copysignf (HUGE_VALF, sinix)
|
||||||
|
* __copysignf (1.0, __real__ x));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -32,8 +32,6 @@ __ccoshl (__complex__ long double x)
|
|||||||
int rcls = fpclassify (__real__ x);
|
int rcls = fpclassify (__real__ x);
|
||||||
int icls = fpclassify (__imag__ x);
|
int icls = fpclassify (__imag__ x);
|
||||||
|
|
||||||
__real__ x = fabsl (__real__ x);
|
|
||||||
|
|
||||||
if (rcls >= FP_ZERO)
|
if (rcls >= FP_ZERO)
|
||||||
{
|
{
|
||||||
/* Real part is finite. */
|
/* Real part is finite. */
|
||||||
@ -67,7 +65,7 @@ __ccoshl (__complex__ long double x)
|
|||||||
{
|
{
|
||||||
/* Imaginary part is 0.0. */
|
/* Imaginary part is 0.0. */
|
||||||
__real__ retval = HUGE_VALL;
|
__real__ retval = HUGE_VALL;
|
||||||
__imag__ retval = __imag__ x;
|
__imag__ retval = __imag__ x * __copysignl (1.0, __real__ x);
|
||||||
}
|
}
|
||||||
else if (icls > FP_ZERO)
|
else if (icls > FP_ZERO)
|
||||||
{
|
{
|
||||||
@ -77,7 +75,8 @@ __ccoshl (__complex__ long double x)
|
|||||||
__sincosl (__imag__ x, &sinix, &cosix);
|
__sincosl (__imag__ x, &sinix, &cosix);
|
||||||
|
|
||||||
__real__ retval = __copysignl (HUGE_VALL, cosix);
|
__real__ retval = __copysignl (HUGE_VALL, cosix);
|
||||||
__imag__ retval = __copysignl (HUGE_VALL, sinix);
|
__imag__ retval = (__copysignl (HUGE_VALL, sinix)
|
||||||
|
* __copysignl (1.0, __real__ x));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include <mach/mig_support.h>
|
#include <mach/mig_support.h>
|
||||||
#include "hurdstartup.h"
|
#include "hurdstartup.h"
|
||||||
#include <mach/host_info.h>
|
#include <mach/host_info.h>
|
||||||
#include "../stdio-common/_itoa.h"
|
#include <stdio-common/_itoa.h>
|
||||||
#include <hurd/auth.h>
|
#include <hurd/auth.h>
|
||||||
#include <hurd/term.h>
|
#include <hurd/term.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -188,6 +188,9 @@ unfmh(); /* XXX */
|
|||||||
/* Set up so we can do RPCs. */
|
/* Set up so we can do RPCs. */
|
||||||
__mach_init ();
|
__mach_init ();
|
||||||
|
|
||||||
|
/* Initialize frequently used global variable. */
|
||||||
|
_dl_pagesize = __getpagesize ();
|
||||||
|
|
||||||
fmh(); /* XXX */
|
fmh(); /* XXX */
|
||||||
|
|
||||||
/* See hurd/hurdstartup.c; this deals with getting information
|
/* See hurd/hurdstartup.c; this deals with getting information
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
|
|
||||||
/* XXX Must this be __PIC__ ? --drepper */
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
.option pic2
|
.option pic2
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
|
|
||||||
/* XXX Must this be __PIC__ ? --drepper */
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
.option pic2
|
.option pic2
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,16 +96,6 @@ elf_machine_matches_host (ElfW(Half) e_machine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
|
|
||||||
+ first element of the GOT. This must be inlined in a function which
|
|
||||||
+ uses global data. */
|
|
||||||
+static inline ElfW(Addr)
|
|
||||||
+elf_machine_dynamic (void)
|
|
||||||
+{
|
|
||||||
+ register ElfW(Addr) gp asm ("$28");
|
|
||||||
+ return * (ElfW(Addr) *) (gp - 0x7ff0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static inline ElfW(Addr) *
|
static inline ElfW(Addr) *
|
||||||
elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
|
elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
|
||||||
{
|
{
|
||||||
|
@ -96,16 +96,6 @@ elf_machine_matches_host (ElfW(Half) e_machine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
|
|
||||||
+ first element of the GOT. This must be inlined in a function which
|
|
||||||
+ uses global data. */
|
|
||||||
+static inline ElfW(Addr)
|
|
||||||
+elf_machine_dynamic (void)
|
|
||||||
+{
|
|
||||||
+ register ElfW(Addr) gp asm ("$28");
|
|
||||||
+ return * (ElfW(Addr) *) (gp - 0x7ff0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static inline ElfW(Addr) *
|
static inline ElfW(Addr) *
|
||||||
elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
|
elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ ENTRY(__udiv_qrnnd)
|
|||||||
!#PROLOGUE# 1
|
!#PROLOGUE# 1
|
||||||
st %i1,[%fp-8]
|
st %i1,[%fp-8]
|
||||||
ld [%fp-8],%f10
|
ld [%fp-8],%f10
|
||||||
#ifdef __PIC__
|
#ifdef PIC
|
||||||
._XL11:
|
._XL11:
|
||||||
call ._XL1
|
call ._XL1
|
||||||
fitod %f10,%f4
|
fitod %f10,%f4
|
||||||
@ -78,7 +78,7 @@ L249:
|
|||||||
faddd %f4,%f8,%f4
|
faddd %f4,%f8,%f4
|
||||||
L250:
|
L250:
|
||||||
fdivd %f2,%f4,%f2
|
fdivd %f2,%f4,%f2
|
||||||
#ifdef __PIC__
|
#ifdef PIC
|
||||||
._XL22:
|
._XL22:
|
||||||
call ._XL2
|
call ._XL2
|
||||||
nop
|
nop
|
||||||
|
@ -19,35 +19,36 @@
|
|||||||
/* This file defines the `errno' constants for standalone ARM machines.
|
/* This file defines the `errno' constants for standalone ARM machines.
|
||||||
These constants are essentially arbitrary. */
|
These constants are essentially arbitrary. */
|
||||||
|
|
||||||
#if !defined(__Emath_defined) && (defined(_ERRNO_H) || defined(__need_Emath))
|
#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)
|
||||||
#undef __need_Emath
|
# undef __need_Emath
|
||||||
#define __Emath_defined 1
|
# define __Emath_defined 1
|
||||||
|
|
||||||
#define EDOM 1
|
# define EDOM 1
|
||||||
#define ERANGE 2
|
# define ERANGE 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _ERRNO_H
|
#ifdef _ERRNO_H
|
||||||
#define ENOSYS 3
|
# define ENOSYS 3
|
||||||
#define EINVAL 4
|
# define EINVAL 4
|
||||||
#define ESPIPE 5
|
# define ESPIPE 5
|
||||||
#define EBADF 6
|
# define EBADF 6
|
||||||
#define ENOMEM 7
|
# define ENOMEM 7
|
||||||
#define EACCES 8
|
# define EACCES 8
|
||||||
#define ENFILE 9
|
# define ENFILE 9
|
||||||
#define EMFILE 10
|
# define EMFILE 10
|
||||||
#define ENAMETOOLONG 11 /* File name too long */
|
# define ENAMETOOLONG 11 /* File name too long */
|
||||||
#define ELOOP 12 /* Too many symbolic links encountered */
|
# define ELOOP 12 /* Too many symbolic links encountered */
|
||||||
#define ENOMSG 13 /* No message of desired type */
|
# define ENOMSG 13 /* No message of desired type */
|
||||||
#define E2BIG 14 /* Arg list too long */
|
# define E2BIG 14 /* Arg list too long */
|
||||||
#define EINTR 15
|
# define EINTR 15
|
||||||
#define EILSEQ 16
|
# define EILSEQ 16
|
||||||
#define ENOEXEC 17
|
# define ENOEXEC 17
|
||||||
#define ENOENT 18
|
# define ENOENT 18
|
||||||
#define EPROTOTYPE 19
|
# define EPROTOTYPE 19
|
||||||
#define ESRCH 20
|
# define ESRCH 20
|
||||||
#define EPERM 21
|
# define EPERM 21
|
||||||
#define ENOTDIR 22
|
# define ENOTDIR 22
|
||||||
|
# define ESTALE 23
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __set_errno(val) errno = (val)
|
#define __set_errno(val) errno = (val)
|
||||||
|
32
sysdeps/standalone/arm/sysdep.c
Normal file
32
sysdeps/standalone/arm/sysdep.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
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 <sysdep.h>
|
||||||
|
|
||||||
|
/* errno has to be defined somewhere, and it might as well be here. */
|
||||||
|
int errno = 0;
|
||||||
|
|
||||||
|
/* The same goes for these magic signal functions. This is a standalone
|
||||||
|
environment so we do nothing. */
|
||||||
|
void _sig_dfl(int sig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sig_ign(int sig)
|
||||||
|
{
|
||||||
|
}
|
@ -29,7 +29,7 @@
|
|||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
ENTRY(__syscall_error)
|
ENTRY(__syscall_error)
|
||||||
#ifdef __PIC__
|
#ifdef PIC
|
||||||
.set noat
|
.set noat
|
||||||
move $1, $31
|
move $1, $31
|
||||||
bltzal $0, 0f
|
bltzal $0, 0f
|
||||||
|
@ -27,18 +27,16 @@
|
|||||||
static inline void
|
static inline void
|
||||||
frob_brk (void)
|
frob_brk (void)
|
||||||
{
|
{
|
||||||
|
extern size_t _dl_pagesize;
|
||||||
extern void _end;
|
extern void _end;
|
||||||
__brk (0); /* Initialize the break. */
|
__brk (0); /* Initialize the break. */
|
||||||
if (__sbrk (0) == &_end)
|
if (__sbrk (0) == &_end)
|
||||||
{
|
/* The dynamic linker was run as a program, and so the initial break
|
||||||
/* The dynamic linker was run as a program, and so the initial break
|
starts just after our bss, at &_end. The malloc in dl-minimal.c
|
||||||
starts just after our bss, at &_end. The malloc in dl-minimal.c
|
will consume the rest of this page, so tell the kernel to move the
|
||||||
will consume the rest of this page, so tell the kernel to move the
|
break up that far. When the user program examines its break, it
|
||||||
break up that far. When the user program examines its break, it
|
will see this new value and not clobber our data. */
|
||||||
will see this new value and not clobber our data. */
|
__sbrk (_dl_pagesize - ((&_end - (void *) 0) & _dl_pagesize));
|
||||||
size_t pg = __getpagesize ();
|
|
||||||
__sbrk (pg - ((&_end - (void *) 0) & pg));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <sysdeps/generic/dl-sysdep.c>
|
#include <sysdeps/generic/dl-sysdep.c>
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
NESTED(__clone,4*SZREG,sp)
|
NESTED(__clone,4*SZREG,sp)
|
||||||
#ifdef __PIC__
|
#ifdef PIC
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.cpload $25
|
.cpload $25
|
||||||
.set reorder
|
.set reorder
|
||||||
|
@ -72,7 +72,7 @@ ENTRY(____sparc_signal_trampoline)
|
|||||||
or %g0,%g0,%g1 /*Call sys_setup */
|
or %g0,%g0,%g1 /*Call sys_setup */
|
||||||
t 0x10
|
t 0x10
|
||||||
1:
|
1:
|
||||||
#ifdef __PIC__
|
#ifdef PIC
|
||||||
/* Save return address */
|
/* Save return address */
|
||||||
mov %o7,%o4
|
mov %o7,%o4
|
||||||
___sxx:
|
___sxx:
|
||||||
@ -89,7 +89,7 @@ ___syy:
|
|||||||
#endif
|
#endif
|
||||||
sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
|
sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
|
||||||
or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
|
or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
|
||||||
#ifdef __PIC__
|
#ifdef PIC
|
||||||
add %o5,%o4,%o4
|
add %o5,%o4,%o4
|
||||||
ld [%o4],%o5
|
ld [%o4],%o5
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user