mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
Compare commits
126
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1494bc3fa2 | ||
|
|
7b77676c2f | ||
|
|
ac4d4092ac | ||
|
|
978044a70e | ||
|
|
14cbd70aa6 | ||
|
|
befe97e0d0 | ||
|
|
0d60d7de5d | ||
|
|
1b88b322d4 | ||
|
|
d3cfe8dd4e | ||
|
|
f9626feb2d | ||
|
|
e797f2e35c | ||
|
|
f2b016bfc9 | ||
|
|
0e7f328d08 | ||
|
|
fd74fc86fd | ||
|
|
ff4eb01a42 | ||
|
|
2f533068b9 | ||
|
|
94db648424 | ||
|
|
37756a8389 | ||
|
|
3b1744f208 | ||
|
|
53bfe35486 | ||
|
|
d5321ea34d | ||
|
|
2a561bf1e1 | ||
|
|
aa8a3b59b1 | ||
|
|
c1f8ef75d3 | ||
|
|
f94203900a | ||
|
|
945a6124b6 | ||
|
|
06bc2b63c8 | ||
|
|
b640e88eff | ||
|
|
f2fad0ae26 | ||
|
|
8a2f63b734 | ||
|
|
7894035e1c | ||
|
|
cc579e4358 | ||
|
|
802ea9dccd | ||
|
|
788b3f7f39 | ||
|
|
5a312412f2 | ||
|
|
3115c839ed | ||
|
|
1b7007d267 | ||
|
|
1c1465a4f7 | ||
|
|
4e2e518f6a | ||
|
|
8c508c82e7 | ||
|
|
19e033b5ff | ||
|
|
a52ef8e416 | ||
|
|
b3c20a361d | ||
|
|
87ffc9aca1 | ||
|
|
8899fb784a | ||
|
|
8ae4ba1c6d | ||
|
|
9abf55c24c | ||
|
|
3504bb650f | ||
|
|
cbf4bcd2b3 | ||
|
|
70ac15e052 | ||
|
|
5acf2e2cb4 | ||
|
|
bb21d92c36 | ||
|
|
80c96e8e6f | ||
|
|
0b5cfa4e0b | ||
|
|
aa85b49673 | ||
|
|
04e35f0daf | ||
|
|
dcd417d9e1 | ||
|
|
8eb6f95371 | ||
|
|
a4947a1a53 | ||
|
|
bba9c68822 | ||
|
|
ace3f2f951 | ||
|
|
c07cf2c353 | ||
|
|
75c95410b7 | ||
|
|
e9e4030ae5 | ||
|
|
c78cb58c50 | ||
|
|
0ad7eada7b | ||
|
|
1670c7cf0d | ||
|
|
be221e8df9 | ||
|
|
3c7dae119e | ||
|
|
56c4396a6e | ||
|
|
4ce1a5c971 | ||
|
|
5852f6de55 | ||
|
|
01682b1f05 | ||
|
|
82496aab64 | ||
|
|
9869e6ec91 | ||
|
|
3ee87ca7d4 | ||
|
|
7dbf6a6cd5 | ||
|
|
8802619dd4 | ||
|
|
8d5be89424 | ||
|
|
0caba1fbdb | ||
|
|
6fb78a8758 | ||
|
|
c25d26bbb4 | ||
|
|
ddbf09971d | ||
|
|
09c3bcb4ad | ||
|
|
fd63f7c6ce | ||
|
|
85148842d4 | ||
|
|
6d96590587 | ||
|
|
b7a09b9201 | ||
|
|
6a87697239 | ||
|
|
bd307f4e23 | ||
|
|
f9ff03a835 | ||
|
|
2b13f2ccc0 | ||
|
|
f1750fb9c6 | ||
|
|
efaf80c5d0 | ||
|
|
959f4c0547 | ||
|
|
627cc92643 | ||
|
|
1b16f19afc | ||
|
|
037c97bbc9 | ||
|
|
bd7c3bed54 | ||
|
|
338cc5101b | ||
|
|
04a9e7f251 | ||
|
|
fd8e1ac720 | ||
|
|
b402c96065 | ||
|
|
5ab387d33b | ||
|
|
ff9e0dc823 | ||
|
|
5d44b2ea72 | ||
|
|
1547e88a9a | ||
|
|
1a19a35223 | ||
|
|
237910315c | ||
|
|
a0d24ebc12 | ||
|
|
1e96287768 | ||
|
|
a1711aa2c9 | ||
|
|
996d168e57 | ||
|
|
05bb11efb2 | ||
|
|
0847bc6ef9 | ||
|
|
f66e5db9b0 | ||
|
|
dc60a4e495 | ||
|
|
c699a3bdd7 | ||
|
|
aaadc59ce1 | ||
|
|
a343cb0f24 | ||
|
|
b9bdb95c3f | ||
|
|
f67c6d9684 | ||
|
|
3cd7504450 | ||
|
|
59ae4124b7 | ||
|
|
ee414d57cf | ||
|
|
b5707b44d2 |
@@ -1352,6 +1352,11 @@
|
||||
* sysdeps/unix/sysv/linux/mips/sys/tas.h: Add missing .mips0 at the
|
||||
end of inline assembler code.
|
||||
|
||||
2000-10-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sunrpc/svc_udp.c (svcudp_recv): Set msg_controllen to all
|
||||
remaining xp_pad space.
|
||||
|
||||
2000-10-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* include/features.h [__USE_FILE_OFFSET && !__REDIRECT]: Define
|
||||
@@ -9280,6 +9285,12 @@
|
||||
syscall.
|
||||
* sysdeps/unix/sysv/linux/mips/truncate64.c: Likewise.
|
||||
|
||||
2000-05-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* resolv/res_query.c (res_nsearch): Remove unused variable
|
||||
root_on_list. If dots >= statp->ndots and as is querydomain
|
||||
fails, keep searching.
|
||||
|
||||
2000-05-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Loose __P.
|
||||
@@ -9480,6 +9491,11 @@
|
||||
* sysdeps/i386/fpu/bits/mathinline.h: Define expm1 inline only if
|
||||
__FAST_MATH__ is defined.
|
||||
|
||||
2000-05-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/i386/fpu/bits/mathinline.h (__expm1_code): Avoid using ?:
|
||||
with omitted middle operand.
|
||||
|
||||
2000-05-22 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* math/Makefile: Add -D__FAST_MATH__ to CFLAGS-test-ifloat.c,
|
||||
@@ -9718,6 +9734,11 @@
|
||||
* manual/arith.texi (Parsing of Integers): Fix typo.
|
||||
Closes PR libc/1744, reported by blp@gnu.org.
|
||||
|
||||
2000-05-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* inet/rcmd.c (rcmd_af): If *ahost cannot be resolved, include
|
||||
unresolved hostname in the message.
|
||||
|
||||
2000-05-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/arm/bits/huge_val.h (HUGE_VAL, HUGE_VALF): Add
|
||||
|
||||
@@ -7729,6 +7729,13 @@
|
||||
|
||||
* Versions.def [ld]: Add GLIBC_2.2.1.
|
||||
|
||||
2001-01-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* malloc/memusage.c (me): If not SUID/SGID, allow creating new
|
||||
$MEMUSAGE_OUTPUT file.
|
||||
* sysdeps/generic/segfault.c (segfault.c): If not SUID/SGID, allow
|
||||
creating new $SEGFAULT_OUTPUT_NAME file.
|
||||
|
||||
2001-01-10 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* elf/dl-libc.c (do_dlopen): Call DL_STATIC_INIT for static binaries.
|
||||
@@ -8130,6 +8137,11 @@
|
||||
* sysdeps/powerpc/soft-fp/Versions: Likewise.
|
||||
* sysdeps/sparc/sparc64/soft-fp/Versions: Likewise.
|
||||
|
||||
2001-01-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* locale/setlocale.c (setlocale): Don't allocate/free category name
|
||||
unnecessarily.
|
||||
|
||||
2001-01-02 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* sysdeps/powerpc/dl-machine.c (__process_machine_rela): Fix typo.
|
||||
|
||||
+24
-51
@@ -452,12 +452,6 @@ link-libc = -Wl,-rpath-link=$(rpath-link) \
|
||||
$(common-objpfx)$(patsubst %,$(libtype.oS),c) $(gnulib)
|
||||
# This is how to find at build-time things that will be installed there.
|
||||
rpath-dirs = math elf dlfcn nss nis rt resolv crypt
|
||||
else
|
||||
ifneq (,$(filter aix aix%,$(config-os)))
|
||||
link-libc = $(common-objpfx)libc.a \
|
||||
$(common-objpfx)$(patsubst %,$(libtype.oS),c) $(gnulib)
|
||||
rpath-dirs = math dlfcn nss nis rt resolv crypt
|
||||
endif
|
||||
endif
|
||||
rpath-link = \
|
||||
$(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
|
||||
@@ -475,13 +469,6 @@ LDFLAGS-rpath-ORIGIN = -Wl,-rpath,'$$ORIGIN'
|
||||
LDFLAGS-soname-fname = -Wl,-soname,$(@F)
|
||||
LDFLAGS-rdynamic = -rdynamic
|
||||
LDFLAGS-Bsymbolic = -Bsymbolic
|
||||
else
|
||||
ifneq (,$(filter aix aix%,$(config-os)))
|
||||
LDFLAGS-rpath-ORIGIN =
|
||||
LDFLAGS-soname-fname =
|
||||
LDFLAGS-rdynamic = -Wl,-bdynamic
|
||||
LDFLAGS-Bsymbolic = -Wl,-bsymbolic
|
||||
endif
|
||||
endif
|
||||
|
||||
# Choose the default search path for the dynamic linker based on
|
||||
@@ -521,18 +508,19 @@ link-libc-bounded = $(common-objpfx)libc_b.a $(gnulib) $(common-objpfx)libc_b.a
|
||||
link-extra-libs-bounded = $(foreach lib,$(LDLIBS-$(@F:%-bp=%)),$(common-objpfx)$(lib)_b.a)
|
||||
|
||||
ifndef gnulib
|
||||
ifneq ($(have-as-needed),yes)
|
||||
libgcc_eh := -lgcc_eh
|
||||
else
|
||||
libgcc_eh := -Wl,--as-needed -lgcc_s$(libgcc_s_suffix) -Wl,--no-as-needed
|
||||
endif
|
||||
ifneq ($(have-cc-with-libunwind),yes)
|
||||
gnulib := -lgcc $(libgcc_eh)
|
||||
static-gnulib := -lgcc -lgcc_eh
|
||||
libunwind =
|
||||
else
|
||||
gnulib := -lgcc $(libgcc_eh) -lunwind
|
||||
static-gnulib := -lgcc -lgcc_eh -lunwind
|
||||
libunwind = -lunwind
|
||||
endif
|
||||
ifneq ($(have-as-needed),yes)
|
||||
libgcc_eh := -lgcc_eh $(libunwind)
|
||||
else
|
||||
libgcc_eh := -Wl,--as-needed -lgcc_s$(libgcc_s_suffix) $(libunwind) -Wl,--no-as-needed
|
||||
endif
|
||||
gnulib := -lgcc $(libgcc_eh)
|
||||
static-gnulib := -lgcc -lgcc_eh $(libunwind)
|
||||
libc.so-gnulib := -lgcc
|
||||
endif
|
||||
ifeq ($(elf),yes)
|
||||
+preinit = $(addprefix $(csu-objpfx),crti.o)
|
||||
@@ -554,7 +542,7 @@ $(subst $(empty) ,:,$(strip $(patsubst -Wl$(comma)-rpath-link=%, %,\
|
||||
$(filter -Wl$(comma)-rpath-link=%,\
|
||||
$(sysdep-LDFLAGS)))))
|
||||
run-program-prefix = $(if $(filter $(notdir $(built-program-file)),\
|
||||
$(tests-static)),, \
|
||||
$(tests-static) $(xtests-static)),, \
|
||||
$(elf-objpfx)$(rtld-installed-name) \
|
||||
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)))
|
||||
else
|
||||
@@ -799,26 +787,19 @@ ifndef avoid-generated
|
||||
# This lets add-ons give more-specific matches that override defaults
|
||||
# in the top-level file.
|
||||
$(common-objpfx)shlib-versions.v.i: \
|
||||
$(wildcard $(patsubst %, $(..)%/shlib-versions,$(add-ons) $(subdirs)))\
|
||||
$(wildcard $(patsubst %, $(..)%/shlib-versions,$(add-ons) \
|
||||
$(config-sysdirs) \
|
||||
$(subdirs))) \
|
||||
$(..)shlib-versions
|
||||
$(common-objpfx)soversions.i: $(common-objpfx)shlib-versions.v
|
||||
default_setname='$(filter-out %_default,$(oldest-abi:%=GLIBC_%))'; \
|
||||
while read conf version setname; do \
|
||||
test -n "$$version" && \
|
||||
test `expr '$(config-machine)-$(config-vendor)-$(config-os)' \
|
||||
: "$$conf"` != 0 || continue; \
|
||||
if test "x$$version" = xDEFAULT; then \
|
||||
default_setname="$$setname"; \
|
||||
else \
|
||||
$(abi-default_setname) \
|
||||
lib=`echo $$version | sed 's/=.*$$//'`; \
|
||||
if eval test -z "\$${versioned_$${lib}}"; then \
|
||||
eval versioned_$${lib}=yes; \
|
||||
number=`echo $$version | sed "s/^.*=//"`; \
|
||||
echo $$lib $$number $${setname:-$${default_setname}}; \
|
||||
fi; \
|
||||
fi; \
|
||||
done < $< > $@T; exit 0
|
||||
|
||||
soversions-default-setname = $(patsubst %, %,\
|
||||
$(filter-out %_default,\
|
||||
$(oldest-abi:%=GLIBC_%)))
|
||||
$(common-objpfx)soversions.i: $(..)scripts/soversions.awk \
|
||||
$(common-objpfx)shlib-versions.v
|
||||
$(AWK) -v default_setname='$(soversions-default-setname)' \
|
||||
-v config='$(config-machine)-$(config-vendor)-$(config-os)' \
|
||||
-f $^ > $@T
|
||||
mv -f $@T $@
|
||||
$(common-objpfx)soversions.mk: $(common-objpfx)soversions.i
|
||||
(while read lib number setname; do \
|
||||
@@ -838,17 +819,10 @@ postclean-generated += soversions.mk soversions.i \
|
||||
shlib-versions.v shlib-versions.v.i
|
||||
|
||||
# Generate the header containing the names of all shared libraries.
|
||||
# We use a stamp file to avoid uncessary recompilations.
|
||||
# We use a stamp file to avoid unnecessary recompilations.
|
||||
before-compile += $(common-objpfx)gnu/lib-names.h
|
||||
ifeq ($(soversions.mk-done),t)
|
||||
$(common-objpfx)gnu/lib-names.h: $(common-objpfx)gnu/lib-names.stmp; @:
|
||||
ifneq (,$(findstring aix,$(config-os)))
|
||||
$(common-objpfx)gnu/lib-names.stmp: $(..)sysdeps/unix/sysv/aix/gnu/lib-names.h
|
||||
$(make-target-directory)
|
||||
@rm -f ${@:stmp=T} $@
|
||||
@cp $(..)sysdeps/unix/sysv/aix/gnu/lib-names.h $(common-objpfx)gnu
|
||||
touch $@
|
||||
else
|
||||
$(common-objpfx)gnu/lib-names.stmp: $(common-objpfx)soversions.mk
|
||||
$(make-target-directory)
|
||||
@rm -f ${@:stmp=T} $@
|
||||
@@ -877,7 +851,6 @@ $(common-objpfx)gnu/lib-names.stmp: $(common-objpfx)soversions.mk
|
||||
$(move-if-change) ${@:stmp=T} ${@:stmp=h}
|
||||
touch $@
|
||||
endif
|
||||
endif
|
||||
|
||||
common-generated += gnu/lib-names.h gnu/lib-names.stmp
|
||||
|
||||
|
||||
@@ -299,9 +299,6 @@ $(foreach dir,$(dist-separate),
|
||||
)
|
||||
endef
|
||||
|
||||
%.bz2: %; bzip2 -9vk $<
|
||||
%.gz: %; gzip -9vnc $< > $@.new && mv -f $@.new $@
|
||||
|
||||
# Do `make dist dist-version=X.Y.Z' to make tar files of an older version.
|
||||
dist-version = $(version)
|
||||
|
||||
|
||||
@@ -581,8 +581,8 @@ build-shlib-objlist = $(build-module-helper-objlist) \
|
||||
# Also omits crti.o and crtn.o, which we do not want
|
||||
# since we define our own `.init' section specially.
|
||||
LDFLAGS-c.so = -nostdlib -nostartfiles
|
||||
# But we still want to link libc.so against $(static-gnulib).
|
||||
LDLIBS-c.so += $(static-gnulib)
|
||||
# But we still want to link libc.so against $(libc.so-gnulib).
|
||||
LDLIBS-c.so += $(libc.so-gnulib)
|
||||
# Give libc.so an entry point and make it directly runnable itself.
|
||||
LDFLAGS-c.so += -e __libc_main
|
||||
# If lazy relocation is disabled add the -z now flag.
|
||||
@@ -1328,6 +1328,8 @@ FORCE:
|
||||
echo-headers:
|
||||
@echo $(headers)
|
||||
|
||||
%.bz2: %; bzip2 -9vk $<
|
||||
%.gz: %; gzip -9vnc $< > $@.new && mv -f $@.new $@
|
||||
|
||||
# Common cleaning targets.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 2004-8-5
|
||||
GNU C Library NEWS -- history of user-visible changes. 2004-10-19
|
||||
Copyright (C) 1992-2002,2003,2004 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
@@ -17,7 +17,7 @@ Version 2.3.4
|
||||
* nscd can now perform SELinux checks.
|
||||
Implemented by Matthew Rickard <mjricka@epoch.ncsc.mil>.
|
||||
|
||||
* getaddrinfo queries are not cached. Canonical name lookup is performed
|
||||
* getaddrinfo queries are now cached. Canonical name lookup is performed
|
||||
efficiently.
|
||||
Implemented by Ulrich Drepper.
|
||||
|
||||
@@ -27,10 +27,20 @@ Version 2.3.4
|
||||
|
||||
* The malloc functions perform more error checking and are stricter when
|
||||
it comes to reacting on errors. The default action is to terminate
|
||||
the process after showing an error message.
|
||||
the process after showing an error message. Implemented by Ulrich Drepper.
|
||||
|
||||
* Reverse lookups of IPv6 addresses does not use bit string or .ip6.int
|
||||
lookups anymore unless explicitly requested.
|
||||
lookups anymore unless explicitly requested. Implemented by Ulrich Drepper.
|
||||
|
||||
* Namespaces in ld.so are implemented. DSOs can be loaded in separate
|
||||
namespaces using the new function dlmopen(). This feature is of course,
|
||||
like most other dynamic loading functionality, not available in statically
|
||||
linked applications. Implemented by Ulrich Drepper.
|
||||
|
||||
* Low-overhead boundary checking variants of string and some stdio functions
|
||||
were added. These are to be used in conjunction with a gcc patch by
|
||||
Jakub Jelinek which adds calls to these functions if possible.
|
||||
Patch by Jakub Jelinek and Ulrich Drepper.
|
||||
|
||||
Version 2.3.3
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Open jobs for finishing GNU libc:
|
||||
---------------------------------
|
||||
Status: September 2002
|
||||
Status: October 2004
|
||||
|
||||
If you have time and talent to take over any of the jobs below please
|
||||
contact <bug-glibc@gnu.org>.
|
||||
@@ -53,7 +53,7 @@ contact <bug-glibc@gnu.org>.
|
||||
|
||||
|
||||
[11] Write access function for netmasks, bootparams, and automount
|
||||
databases for nss_files and nss_db module.
|
||||
databases for nss_files, nss_nis, and nss_nisplus modules.
|
||||
The functions should be embedded in the nss scheme. This is not
|
||||
hard and not all services must be supported at once.
|
||||
|
||||
@@ -76,7 +76,7 @@ contact <bug-glibc@gnu.org>.
|
||||
[18] Based on the sprof program we need tools to analyze the output. The
|
||||
result should be a link map which specifies in which order the .o
|
||||
files are placed in the shared object. This should help to improve
|
||||
code locality and result in a smaller foorprint (in code and data
|
||||
code locality and result in a smaller footprint (in code and data
|
||||
memory) since less pages are only used in small parts.
|
||||
|
||||
|
||||
@@ -93,29 +93,6 @@ contact <bug-glibc@gnu.org>.
|
||||
available.
|
||||
|
||||
|
||||
[21] The nscd program and the stubs in the libc should be changed so
|
||||
that each program uses only one socket connect. Take a look at
|
||||
http://people.redhat.com/drepper/nscd.html
|
||||
|
||||
An alternative approach is to use an mmap()ed file. The idea is
|
||||
the following:
|
||||
- the nscd creates the hash tables and the information it stores
|
||||
in it in a mmap()ed region. This means no pointers must be
|
||||
used, only offsets.
|
||||
OR
|
||||
if POSIX shared memory is available use a named shared memory
|
||||
region to put the data in
|
||||
- each program using NSS functionality tries to open the file
|
||||
with the data.
|
||||
- by checking some timestamp (which the nscd renews frequently)
|
||||
the programs can test whether the file is still valid
|
||||
- if the file is valid look through the nscd and locate the
|
||||
appropriate hash table for the database and lookup the data.
|
||||
If it is included we are set.
|
||||
- if the data is not yet in the database we contact the nscd using
|
||||
the currently implemented methods.
|
||||
|
||||
|
||||
[23] The `strptime' function needs to be completed. This includes among
|
||||
other things that it must get teached about timezones. The solution
|
||||
envisioned is to extract the timezones from the ADO timezone
|
||||
@@ -127,18 +104,4 @@ contact <bug-glibc@gnu.org>.
|
||||
Australia/Canberra or if the current locale is en_AU.
|
||||
|
||||
|
||||
[25] Sun's nscd version implements a feature where the nscd keeps N entries
|
||||
for each database current. I.e., if an entries lifespan is over and
|
||||
it is one of the N entries to be kept the nscd updates the information
|
||||
instead of removing the entry.
|
||||
|
||||
How to decide about which N entries to keep has to be examined.
|
||||
Factors should be number of uses (of course), influenced by aging.
|
||||
Just imagine a computer used by several people. The IDs of the current
|
||||
user should be preferred even if the last user spent more time.
|
||||
|
||||
|
||||
[27] We need a second test suite with tests which cannot run during a normal
|
||||
`make check' run. This test suite can require root priviledges and
|
||||
can test things like DNS (i.e., require network access),
|
||||
user-interaction, networking in general, and probably many other things.
|
||||
[27] ...deleted...
|
||||
|
||||
@@ -104,7 +104,7 @@ endif
|
||||
|
||||
ifeq ($(build-programs),yes)
|
||||
binaries-all = $(others) $(sysdep-others) $(tests) $(xtests) $(test-srcs)
|
||||
binaries-static = $(others-static) $(tests-static)
|
||||
binaries-static = $(others-static) $(tests-static) $(xtests-static)
|
||||
else
|
||||
binaries-all = $(tests) $(xtests) $(test-srcs)
|
||||
binaries-static =
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* Real definitions for extern inline functions in argp-fmtstream.h
|
||||
Copyright (C) 1997, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#define ARGP_FS_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__
|
||||
#define __OPTIMIZE__ 1
|
||||
#include "argp-fmtstream.h"
|
||||
|
||||
#if 0
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* Real definitions for extern inline functions in argp.h
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#endif
|
||||
#define ARGP_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__
|
||||
#define __OPTIMIZE__ 1
|
||||
#include "argp.h"
|
||||
|
||||
/* Add weak aliases. */
|
||||
|
||||
+3
-20
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991,1992,1994-2001,2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991,1992,1994-2001,2003,2004 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
|
||||
@@ -84,33 +84,16 @@ extern void __assert (const char *__assertion, const char *__file, int __line)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
/* For the macro definition we use gcc's __builtin_expect if possible
|
||||
to generate good code for the non-error case. gcc 3.0 is a good
|
||||
enough estimate for when the feature became available. */
|
||||
# if __GNUC_PREREQ (3, 0)
|
||||
# define assert(expr) \
|
||||
(__ASSERT_VOID_CAST (__builtin_expect (!!(expr), 1) ? 0 : \
|
||||
(__assert_fail (__STRING(expr), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# else
|
||||
# define assert(expr) \
|
||||
# define assert(expr) \
|
||||
(__ASSERT_VOID_CAST ((expr) ? 0 : \
|
||||
(__assert_fail (__STRING(expr), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# endif
|
||||
|
||||
# ifdef __USE_GNU
|
||||
# if __GNUC_PREREQ (3, 0)
|
||||
# define assert_perror(errnum) \
|
||||
(__ASSERT_VOID_CAST (__builtin_expect (!(errnum), 1) ? 0 : \
|
||||
(__assert_perror_fail ((errnum), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# else
|
||||
# define assert_perror(errnum) \
|
||||
# define assert_perror(errnum) \
|
||||
(__ASSERT_VOID_CAST (!(errnum) ? 0 : \
|
||||
(__assert_perror_fail ((errnum), __FILE__, __LINE__, \
|
||||
__ASSERT_FUNCTION), 0)))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/* Macros to swap the order of bytes in integer values.
|
||||
Copyright (C) 1997, 1998, 2000, 2001, 2002 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
|
||||
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H 1
|
||||
|
||||
/* Swap bytes in 16 bit value. */
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_16(x) \
|
||||
(__extension__ \
|
||||
({ unsigned short int __bsx = (x); \
|
||||
((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
|
||||
#else
|
||||
static __inline unsigned short int
|
||||
__bswap_16 (unsigned short int __bsx)
|
||||
{
|
||||
return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Swap bytes in 32 bit value. */
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ unsigned int __bsx = (x); \
|
||||
((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \
|
||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))
|
||||
#else
|
||||
static __inline unsigned int
|
||||
__bswap_32 (unsigned int __bsx)
|
||||
{
|
||||
return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |
|
||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
/* Swap bytes in 64 bit value. */
|
||||
# define __bswap_constant_64(x) \
|
||||
((((x) & 0xff00000000000000ull) >> 56) \
|
||||
| (((x) & 0x00ff000000000000ull) >> 40) \
|
||||
| (((x) & 0x0000ff0000000000ull) >> 24) \
|
||||
| (((x) & 0x000000ff00000000ull) >> 8) \
|
||||
| (((x) & 0x00000000ff000000ull) << 8) \
|
||||
| (((x) & 0x0000000000ff0000ull) << 24) \
|
||||
| (((x) & 0x000000000000ff00ull) << 40) \
|
||||
| (((x) & 0x00000000000000ffull) << 56))
|
||||
|
||||
# define __bswap_64(x) \
|
||||
(__extension__ \
|
||||
({ union { __extension__ unsigned long long int __ll; \
|
||||
unsigned int __l[2]; } __w, __r; \
|
||||
if (__builtin_constant_p (x)) \
|
||||
__r.__ll = __bswap_constant_64 (x); \
|
||||
else \
|
||||
{ \
|
||||
__w.__ll = (x); \
|
||||
__r.__l[0] = __bswap_32 (__w.__l[1]); \
|
||||
__r.__l[1] = __bswap_32 (__w.__l[0]); \
|
||||
} \
|
||||
__r.__ll; }))
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_BYTESWAP_H */
|
||||
-596
@@ -1,596 +0,0 @@
|
||||
/* `sysconf', `pathconf', and `confstr' NAME values. Generic version.
|
||||
Copyright (C) 1993,1995-1998,2000,2001,2003,2004
|
||||
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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never use <bits/confname.h> directly; include <unistd.h> instead."
|
||||
#endif
|
||||
|
||||
/* Values for the NAME argument to `pathconf' and `fpathconf'. */
|
||||
enum
|
||||
{
|
||||
_PC_LINK_MAX,
|
||||
#define _PC_LINK_MAX _PC_LINK_MAX
|
||||
_PC_MAX_CANON,
|
||||
#define _PC_MAX_CANON _PC_MAX_CANON
|
||||
_PC_MAX_INPUT,
|
||||
#define _PC_MAX_INPUT _PC_MAX_INPUT
|
||||
_PC_NAME_MAX,
|
||||
#define _PC_NAME_MAX _PC_NAME_MAX
|
||||
_PC_PATH_MAX,
|
||||
#define _PC_PATH_MAX _PC_PATH_MAX
|
||||
_PC_PIPE_BUF,
|
||||
#define _PC_PIPE_BUF _PC_PIPE_BUF
|
||||
_PC_CHOWN_RESTRICTED,
|
||||
#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED
|
||||
_PC_NO_TRUNC,
|
||||
#define _PC_NO_TRUNC _PC_NO_TRUNC
|
||||
_PC_VDISABLE,
|
||||
#define _PC_VDISABLE _PC_VDISABLE
|
||||
_PC_SYNC_IO,
|
||||
#define _PC_SYNC_IO _PC_SYNC_IO
|
||||
_PC_ASYNC_IO,
|
||||
#define _PC_ASYNC_IO _PC_ASYNC_IO
|
||||
_PC_PRIO_IO,
|
||||
#define _PC_PRIO_IO _PC_PRIO_IO
|
||||
_PC_SOCK_MAXBUF,
|
||||
#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF
|
||||
_PC_FILESIZEBITS,
|
||||
#define _PC_FILESIZEBITS _PC_FILESIZEBITS
|
||||
_PC_REC_INCR_XFER_SIZE,
|
||||
#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE
|
||||
_PC_REC_MAX_XFER_SIZE,
|
||||
#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE
|
||||
_PC_REC_MIN_XFER_SIZE,
|
||||
#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE
|
||||
_PC_REC_XFER_ALIGN,
|
||||
#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN
|
||||
_PC_ALLOC_SIZE_MIN,
|
||||
#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN
|
||||
_PC_SYMLINK_MAX,
|
||||
#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX
|
||||
_PC_2_SYMLINKS
|
||||
#define _PC_2_SYMLINKS _PC_2_SYMLINKS
|
||||
};
|
||||
|
||||
/* Values for the argument to `sysconf'. */
|
||||
enum
|
||||
{
|
||||
_SC_ARG_MAX,
|
||||
#define _SC_ARG_MAX _SC_ARG_MAX
|
||||
_SC_CHILD_MAX,
|
||||
#define _SC_CHILD_MAX _SC_CHILD_MAX
|
||||
_SC_CLK_TCK,
|
||||
#define _SC_CLK_TCK _SC_CLK_TCK
|
||||
_SC_NGROUPS_MAX,
|
||||
#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX
|
||||
_SC_OPEN_MAX,
|
||||
#define _SC_OPEN_MAX _SC_OPEN_MAX
|
||||
_SC_STREAM_MAX,
|
||||
#define _SC_STREAM_MAX _SC_STREAM_MAX
|
||||
_SC_TZNAME_MAX,
|
||||
#define _SC_TZNAME_MAX _SC_TZNAME_MAX
|
||||
_SC_JOB_CONTROL,
|
||||
#define _SC_JOB_CONTROL _SC_JOB_CONTROL
|
||||
_SC_SAVED_IDS,
|
||||
#define _SC_SAVED_IDS _SC_SAVED_IDS
|
||||
_SC_REALTIME_SIGNALS,
|
||||
#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS
|
||||
_SC_PRIORITY_SCHEDULING,
|
||||
#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING
|
||||
_SC_TIMERS,
|
||||
#define _SC_TIMERS _SC_TIMERS
|
||||
_SC_ASYNCHRONOUS_IO,
|
||||
#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO
|
||||
_SC_PRIORITIZED_IO,
|
||||
#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO
|
||||
_SC_SYNCHRONIZED_IO,
|
||||
#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO
|
||||
_SC_FSYNC,
|
||||
#define _SC_FSYNC _SC_FSYNC
|
||||
_SC_MAPPED_FILES,
|
||||
#define _SC_MAPPED_FILES _SC_MAPPED_FILES
|
||||
_SC_MEMLOCK,
|
||||
#define _SC_MEMLOCK _SC_MEMLOCK
|
||||
_SC_MEMLOCK_RANGE,
|
||||
#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE
|
||||
_SC_MEMORY_PROTECTION,
|
||||
#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION
|
||||
_SC_MESSAGE_PASSING,
|
||||
#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING
|
||||
_SC_SEMAPHORES,
|
||||
#define _SC_SEMAPHORES _SC_SEMAPHORES
|
||||
_SC_SHARED_MEMORY_OBJECTS,
|
||||
#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS
|
||||
_SC_AIO_LISTIO_MAX,
|
||||
#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX
|
||||
_SC_AIO_MAX,
|
||||
#define _SC_AIO_MAX _SC_AIO_MAX
|
||||
_SC_AIO_PRIO_DELTA_MAX,
|
||||
#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX
|
||||
_SC_DELAYTIMER_MAX,
|
||||
#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX
|
||||
_SC_MQ_OPEN_MAX,
|
||||
#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX
|
||||
_SC_MQ_PRIO_MAX,
|
||||
#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX
|
||||
_SC_VERSION,
|
||||
#define _SC_VERSION _SC_VERSION
|
||||
_SC_PAGESIZE,
|
||||
#define _SC_PAGESIZE _SC_PAGESIZE
|
||||
#define _SC_PAGE_SIZE _SC_PAGESIZE
|
||||
_SC_RTSIG_MAX,
|
||||
#define _SC_RTSIG_MAX _SC_RTSIG_MAX
|
||||
_SC_SEM_NSEMS_MAX,
|
||||
#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX
|
||||
_SC_SEM_VALUE_MAX,
|
||||
#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX
|
||||
_SC_SIGQUEUE_MAX,
|
||||
#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX
|
||||
_SC_TIMER_MAX,
|
||||
#define _SC_TIMER_MAX _SC_TIMER_MAX
|
||||
|
||||
/* Values for the argument to `sysconf'
|
||||
corresponding to _POSIX2_* symbols. */
|
||||
_SC_BC_BASE_MAX,
|
||||
#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX
|
||||
_SC_BC_DIM_MAX,
|
||||
#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX
|
||||
_SC_BC_SCALE_MAX,
|
||||
#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX
|
||||
_SC_BC_STRING_MAX,
|
||||
#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX
|
||||
_SC_COLL_WEIGHTS_MAX,
|
||||
#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX
|
||||
_SC_EQUIV_CLASS_MAX,
|
||||
#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX
|
||||
_SC_EXPR_NEST_MAX,
|
||||
#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX
|
||||
_SC_LINE_MAX,
|
||||
#define _SC_LINE_MAX _SC_LINE_MAX
|
||||
_SC_RE_DUP_MAX,
|
||||
#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX
|
||||
_SC_CHARCLASS_NAME_MAX,
|
||||
#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX
|
||||
|
||||
_SC_2_VERSION,
|
||||
#define _SC_2_VERSION _SC_2_VERSION
|
||||
_SC_2_C_BIND,
|
||||
#define _SC_2_C_BIND _SC_2_C_BIND
|
||||
_SC_2_C_DEV,
|
||||
#define _SC_2_C_DEV _SC_2_C_DEV
|
||||
_SC_2_FORT_DEV,
|
||||
#define _SC_2_FORT_DEV _SC_2_FORT_DEV
|
||||
_SC_2_FORT_RUN,
|
||||
#define _SC_2_FORT_RUN _SC_2_FORT_RUN
|
||||
_SC_2_SW_DEV,
|
||||
#define _SC_2_SW_DEV _SC_2_SW_DEV
|
||||
_SC_2_LOCALEDEF,
|
||||
#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF
|
||||
|
||||
_SC_PII,
|
||||
#define _SC_PII _SC_PII
|
||||
_SC_PII_XTI,
|
||||
#define _SC_PII_XTI _SC_PII_XTI
|
||||
_SC_PII_SOCKET,
|
||||
#define _SC_PII_SOCKET _SC_PII_SOCKET
|
||||
_SC_PII_INTERNET,
|
||||
#define _SC_PII_INTERNET _SC_PII_INTERNET
|
||||
_SC_PII_OSI,
|
||||
#define _SC_PII_OSI _SC_PII_OSI
|
||||
_SC_POLL,
|
||||
#define _SC_POLL _SC_POLL
|
||||
_SC_SELECT,
|
||||
#define _SC_SELECT _SC_SELECT
|
||||
_SC_UIO_MAXIOV,
|
||||
#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV
|
||||
_SC_IOV_MAX = _SC_UIO_MAXIOV,
|
||||
#define _SC_IOV_MAX _SC_IOV_MAX
|
||||
_SC_PII_INTERNET_STREAM,
|
||||
#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM
|
||||
_SC_PII_INTERNET_DGRAM,
|
||||
#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM
|
||||
_SC_PII_OSI_COTS,
|
||||
#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS
|
||||
_SC_PII_OSI_CLTS,
|
||||
#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS
|
||||
_SC_PII_OSI_M,
|
||||
#define _SC_PII_OSI_M _SC_PII_OSI_M
|
||||
_SC_T_IOV_MAX,
|
||||
#define _SC_T_IOV_MAX _SC_T_IOV_MAX
|
||||
|
||||
/* Values according to POSIX 1003.1c (POSIX threads). */
|
||||
_SC_THREADS,
|
||||
#define _SC_THREADS _SC_THREADS
|
||||
_SC_THREAD_SAFE_FUNCTIONS,
|
||||
#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS
|
||||
_SC_GETGR_R_SIZE_MAX,
|
||||
#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX
|
||||
_SC_GETPW_R_SIZE_MAX,
|
||||
#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX
|
||||
_SC_LOGIN_NAME_MAX,
|
||||
#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX
|
||||
_SC_TTY_NAME_MAX,
|
||||
#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX
|
||||
_SC_THREAD_DESTRUCTOR_ITERATIONS,
|
||||
#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
|
||||
_SC_THREAD_KEYS_MAX,
|
||||
#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX
|
||||
_SC_THREAD_STACK_MIN,
|
||||
#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN
|
||||
_SC_THREAD_THREADS_MAX,
|
||||
#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX
|
||||
_SC_THREAD_ATTR_STACKADDR,
|
||||
#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR
|
||||
_SC_THREAD_ATTR_STACKSIZE,
|
||||
#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE
|
||||
_SC_THREAD_PRIORITY_SCHEDULING,
|
||||
#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING
|
||||
_SC_THREAD_PRIO_INHERIT,
|
||||
#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT
|
||||
_SC_THREAD_PRIO_PROTECT,
|
||||
#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT
|
||||
_SC_THREAD_PROCESS_SHARED,
|
||||
#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED
|
||||
|
||||
_SC_NPROCESSORS_CONF,
|
||||
#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF
|
||||
_SC_NPROCESSORS_ONLN,
|
||||
#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN
|
||||
_SC_PHYS_PAGES,
|
||||
#define _SC_PHYS_PAGES _SC_PHYS_PAGES
|
||||
_SC_AVPHYS_PAGES,
|
||||
#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES
|
||||
_SC_ATEXIT_MAX,
|
||||
#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX
|
||||
_SC_PASS_MAX,
|
||||
#define _SC_PASS_MAX _SC_PASS_MAX
|
||||
|
||||
_SC_XOPEN_VERSION,
|
||||
#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION
|
||||
_SC_XOPEN_XCU_VERSION,
|
||||
#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION
|
||||
_SC_XOPEN_UNIX,
|
||||
#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX
|
||||
_SC_XOPEN_CRYPT,
|
||||
#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT
|
||||
_SC_XOPEN_ENH_I18N,
|
||||
#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N
|
||||
_SC_XOPEN_SHM,
|
||||
#define _SC_XOPEN_SHM _SC_XOPEN_SHM
|
||||
|
||||
_SC_2_CHAR_TERM,
|
||||
#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM
|
||||
_SC_2_C_VERSION,
|
||||
#define _SC_2_C_VERSION _SC_2_C_VERSION
|
||||
_SC_2_UPE,
|
||||
#define _SC_2_UPE _SC_2_UPE
|
||||
|
||||
_SC_XOPEN_XPG2,
|
||||
#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2
|
||||
_SC_XOPEN_XPG3,
|
||||
#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3
|
||||
_SC_XOPEN_XPG4,
|
||||
#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4
|
||||
|
||||
_SC_CHAR_BIT,
|
||||
#define _SC_CHAR_BIT _SC_CHAR_BIT
|
||||
_SC_CHAR_MAX,
|
||||
#define _SC_CHAR_MAX _SC_CHAR_MAX
|
||||
_SC_CHAR_MIN,
|
||||
#define _SC_CHAR_MIN _SC_CHAR_MIN
|
||||
_SC_INT_MAX,
|
||||
#define _SC_INT_MAX _SC_INT_MAX
|
||||
_SC_INT_MIN,
|
||||
#define _SC_INT_MIN _SC_INT_MIN
|
||||
_SC_LONG_BIT,
|
||||
#define _SC_LONG_BIT _SC_LONG_BIT
|
||||
_SC_WORD_BIT,
|
||||
#define _SC_WORD_BIT _SC_WORD_BIT
|
||||
_SC_MB_LEN_MAX,
|
||||
#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX
|
||||
_SC_NZERO,
|
||||
#define _SC_NZERO _SC_NZERO
|
||||
_SC_SSIZE_MAX,
|
||||
#define _SC_SSIZE_MAX _SC_SSIZE_MAX
|
||||
_SC_SCHAR_MAX,
|
||||
#define _SC_SCHAR_MAX _SC_SCHAR_MAX
|
||||
_SC_SCHAR_MIN,
|
||||
#define _SC_SCHAR_MIN _SC_SCHAR_MIN
|
||||
_SC_SHRT_MAX,
|
||||
#define _SC_SHRT_MAX _SC_SHRT_MAX
|
||||
_SC_SHRT_MIN,
|
||||
#define _SC_SHRT_MIN _SC_SHRT_MIN
|
||||
_SC_UCHAR_MAX,
|
||||
#define _SC_UCHAR_MAX _SC_UCHAR_MAX
|
||||
_SC_UINT_MAX,
|
||||
#define _SC_UINT_MAX _SC_UINT_MAX
|
||||
_SC_ULONG_MAX,
|
||||
#define _SC_ULONG_MAX _SC_ULONG_MAX
|
||||
_SC_USHRT_MAX,
|
||||
#define _SC_USHRT_MAX _SC_USHRT_MAX
|
||||
|
||||
_SC_NL_ARGMAX,
|
||||
#define _SC_NL_ARGMAX _SC_NL_ARGMAX
|
||||
_SC_NL_LANGMAX,
|
||||
#define _SC_NL_LANGMAX _SC_NL_LANGMAX
|
||||
_SC_NL_MSGMAX,
|
||||
#define _SC_NL_MSGMAX _SC_NL_MSGMAX
|
||||
_SC_NL_NMAX,
|
||||
#define _SC_NL_NMAX _SC_NL_NMAX
|
||||
_SC_NL_SETMAX,
|
||||
#define _SC_NL_SETMAX _SC_NL_SETMAX
|
||||
_SC_NL_TEXTMAX,
|
||||
#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX
|
||||
|
||||
_SC_XBS5_ILP32_OFF32,
|
||||
#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32
|
||||
_SC_XBS5_ILP32_OFFBIG,
|
||||
#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG
|
||||
_SC_XBS5_LP64_OFF64,
|
||||
#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64
|
||||
_SC_XBS5_LPBIG_OFFBIG,
|
||||
#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG
|
||||
|
||||
_SC_XOPEN_LEGACY,
|
||||
#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY
|
||||
_SC_XOPEN_REALTIME,
|
||||
#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME
|
||||
_SC_XOPEN_REALTIME_THREADS,
|
||||
#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS
|
||||
|
||||
_SC_ADVISORY_INFO,
|
||||
#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO
|
||||
_SC_BARRIERS,
|
||||
#define _SC_BARRIERS _SC_BARRIERS
|
||||
_SC_BASE,
|
||||
#define _SC_BASE _SC_BASE
|
||||
_SC_C_LANG_SUPPORT,
|
||||
#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT
|
||||
_SC_C_LANG_SUPPORT_R,
|
||||
#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R
|
||||
_SC_CLOCK_SELECTION,
|
||||
#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION
|
||||
_SC_CPUTIME,
|
||||
#define _SC_CPUTIME _SC_CPUTIME
|
||||
_SC_THREAD_CPUTIME,
|
||||
#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME
|
||||
_SC_DEVICE_IO,
|
||||
#define _SC_DEVICE_IO _SC_DEVICE_IO
|
||||
_SC_DEVICE_SPECIFIC,
|
||||
#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC
|
||||
_SC_DEVICE_SPECIFIC_R,
|
||||
#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R
|
||||
_SC_FD_MGMT,
|
||||
#define _SC_FD_MGMT _SC_FD_MGMT
|
||||
_SC_FIFO,
|
||||
#define _SC_FIFO _SC_FIFO
|
||||
_SC_PIPE,
|
||||
#define _SC_PIPE _SC_PIPE
|
||||
_SC_FILE_ATTRIBUTES,
|
||||
#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES
|
||||
_SC_FILE_LOCKING,
|
||||
#define _SC_FILE_LOCKING _SC_FILE_LOCKING
|
||||
_SC_FILE_SYSTEM,
|
||||
#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM
|
||||
_SC_MONOTONIC_CLOCK,
|
||||
#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK
|
||||
_SC_MULTI_PROCESS,
|
||||
#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS
|
||||
_SC_SINGLE_PROCESS,
|
||||
#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS
|
||||
_SC_NETWORKING,
|
||||
#define _SC_NETWORKING _SC_NETWORKING
|
||||
_SC_READER_WRITER_LOCKS,
|
||||
#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS
|
||||
_SC_SPIN_LOCKS,
|
||||
#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS
|
||||
_SC_REGEXP,
|
||||
#define _SC_REGEXP _SC_REGEXP
|
||||
_SC_REGEX_VERSION,
|
||||
#define _SC_REGEX_VERSION _SC_REGEX_VERSION
|
||||
_SC_SHELL,
|
||||
#define _SC_SHELL _SC_SHELL
|
||||
_SC_SIGNALS,
|
||||
#define _SC_SIGNALS _SC_SIGNALS
|
||||
_SC_SPAWN,
|
||||
#define _SC_SPAWN _SC_SPAWN
|
||||
_SC_SPORADIC_SERVER,
|
||||
#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER
|
||||
_SC_THREAD_SPORADIC_SERVER,
|
||||
#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER
|
||||
_SC_SYSTEM_DATABASE,
|
||||
#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE
|
||||
_SC_SYSTEM_DATABASE_R,
|
||||
#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R
|
||||
_SC_TIMEOUTS,
|
||||
#define _SC_TIMEOUTS _SC_TIMEOUTS
|
||||
_SC_TYPED_MEMORY_OBJECTS,
|
||||
#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS
|
||||
_SC_USER_GROUPS,
|
||||
#define _SC_USER_GROUPS _SC_USER_GROUPS
|
||||
_SC_USER_GROUPS_R,
|
||||
#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R
|
||||
_SC_2_PBS,
|
||||
#define _SC_2_PBS _SC_2_PBS
|
||||
_SC_2_PBS_ACCOUNTING,
|
||||
#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING
|
||||
_SC_2_PBS_LOCATE,
|
||||
#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE
|
||||
_SC_2_PBS_MESSAGE,
|
||||
#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE
|
||||
_SC_2_PBS_TRACK,
|
||||
#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK
|
||||
_SC_SYMLOOP_MAX,
|
||||
#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX
|
||||
_SC_STREAMS,
|
||||
#define _SC_STREAMS _SC_STREAMS
|
||||
_SC_2_PBS_CHECKPOINT,
|
||||
#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT
|
||||
|
||||
_SC_V6_ILP32_OFF32,
|
||||
#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32
|
||||
_SC_V6_ILP32_OFFBIG,
|
||||
#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG
|
||||
_SC_V6_LP64_OFF64,
|
||||
#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64
|
||||
_SC_V6_LPBIG_OFFBIG,
|
||||
#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG
|
||||
|
||||
_SC_HOST_NAME_MAX,
|
||||
#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX
|
||||
_SC_TRACE,
|
||||
#define _SC_TRACE _SC_TRACE
|
||||
_SC_TRACE_EVENT_FILTER,
|
||||
#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER
|
||||
_SC_TRACE_INHERIT,
|
||||
#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT
|
||||
_SC_TRACE_LOG,
|
||||
#define _SC_TRACE_LOG _SC_TRACE_LOG
|
||||
|
||||
_SC_LEVEL1_ICACHE_SIZE,
|
||||
#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE
|
||||
_SC_LEVEL1_ICACHE_ASSOC,
|
||||
#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC
|
||||
_SC_LEVEL1_ICACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE
|
||||
_SC_LEVEL1_DCACHE_SIZE,
|
||||
#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE
|
||||
_SC_LEVEL1_DCACHE_ASSOC,
|
||||
#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC
|
||||
_SC_LEVEL1_DCACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE
|
||||
_SC_LEVEL2_CACHE_SIZE,
|
||||
#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE
|
||||
_SC_LEVEL2_CACHE_ASSOC,
|
||||
#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC
|
||||
_SC_LEVEL2_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE
|
||||
_SC_LEVEL3_CACHE_SIZE,
|
||||
#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE
|
||||
_SC_LEVEL3_CACHE_ASSOC,
|
||||
#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC
|
||||
_SC_LEVEL3_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE
|
||||
_SC_LEVEL4_CACHE_SIZE,
|
||||
#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE
|
||||
_SC_LEVEL4_CACHE_ASSOC,
|
||||
#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC
|
||||
_SC_LEVEL4_CACHE_LINESIZE
|
||||
#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE
|
||||
/* Leave room here, maybe we need a few more cache levels some day. */
|
||||
};
|
||||
|
||||
/* Values for the NAME argument to `confstr'. */
|
||||
enum
|
||||
{
|
||||
_CS_PATH, /* The default search path. */
|
||||
#define _CS_PATH _CS_PATH
|
||||
|
||||
_CS_V6_WIDTH_RESTRICTED_ENVS,
|
||||
# define _CS_V6_WIDTH_RESTRICTED_ENVS _CS_V6_WIDTH_RESTRICTED_ENVS
|
||||
|
||||
_CS_GNU_LIBC_VERSION,
|
||||
#define _CS_GNU_LIBC_VERSION _CS_GNU_LIBC_VERSION
|
||||
_CS_GNU_LIBPTHREAD_VERSION,
|
||||
#define _CS_GNU_LIBPTHREAD_VERSION _CS_GNU_LIBPTHREAD_VERSION
|
||||
|
||||
_CS_LFS_CFLAGS = 1000,
|
||||
#define _CS_LFS_CFLAGS _CS_LFS_CFLAGS
|
||||
_CS_LFS_LDFLAGS,
|
||||
#define _CS_LFS_LDFLAGS _CS_LFS_LDFLAGS
|
||||
_CS_LFS_LIBS,
|
||||
#define _CS_LFS_LIBS _CS_LFS_LIBS
|
||||
_CS_LFS_LINTFLAGS,
|
||||
#define _CS_LFS_LINTFLAGS _CS_LFS_LINTFLAGS
|
||||
_CS_LFS64_CFLAGS,
|
||||
#define _CS_LFS64_CFLAGS _CS_LFS64_CFLAGS
|
||||
_CS_LFS64_LDFLAGS,
|
||||
#define _CS_LFS64_LDFLAGS _CS_LFS64_LDFLAGS
|
||||
_CS_LFS64_LIBS,
|
||||
#define _CS_LFS64_LIBS _CS_LFS64_LIBS
|
||||
_CS_LFS64_LINTFLAGS,
|
||||
#define _CS_LFS64_LINTFLAGS _CS_LFS64_LINTFLAGS
|
||||
|
||||
_CS_XBS5_ILP32_OFF32_CFLAGS = 1100,
|
||||
#define _CS_XBS5_ILP32_OFF32_CFLAGS _CS_XBS5_ILP32_OFF32_CFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LDFLAGS _CS_XBS5_ILP32_OFF32_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LIBS _CS_XBS5_ILP32_OFF32_LIBS
|
||||
_CS_XBS5_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LINTFLAGS _CS_XBS5_ILP32_OFF32_LINTFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_CFLAGS _CS_XBS5_ILP32_OFFBIG_CFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS _CS_XBS5_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LIBS _CS_XBS5_ILP32_OFFBIG_LIBS
|
||||
_CS_XBS5_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_XBS5_LP64_OFF64_CFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_CFLAGS _CS_XBS5_LP64_OFF64_CFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LDFLAGS _CS_XBS5_LP64_OFF64_LDFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LIBS,
|
||||
#define _CS_XBS5_LP64_OFF64_LIBS _CS_XBS5_LP64_OFF64_LIBS
|
||||
_CS_XBS5_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LINTFLAGS _CS_XBS5_LP64_OFF64_LINTFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS _CS_XBS5_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LIBS _CS_XBS5_LPBIG_OFFBIG_LIBS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
|
||||
|
||||
_CS_POSIX_V6_ILP32_OFF32_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS _CS_POSIX_V6_ILP32_OFF32_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LIBS _CS_POSIX_V6_ILP32_OFF32_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS _CS_POSIX_V6_ILP32_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_CFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_CFLAGS _CS_POSIX_V6_LP64_OFF64_CFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS _CS_POSIX_V6_LP64_OFF64_LDFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LIBS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LIBS _CS_POSIX_V6_LP64_OFF64_LIBS
|
||||
_CS_POSIX_V6_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
};
|
||||
@@ -1,64 +0,0 @@
|
||||
/* System dependent definitions for run-time dynamic loading.
|
||||
Copyright (C) 1996,1997,1998,1999,2000,2001 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DLFCN_H
|
||||
# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x00001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x00002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00004 /* Do not load the object. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x00100
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
these calls do not use the PLT. But this would mean the dynamic
|
||||
loader has no chance to find out when the function is called. The
|
||||
macro applies the necessary magic so that profiling is possible.
|
||||
Rewrite
|
||||
foo = (*fctp) (arg1, arg2);
|
||||
into
|
||||
foo = DL_CALL_FCT (fctp, (arg1, arg2));
|
||||
*/
|
||||
# define DL_CALL_FCT(fctp, args) \
|
||||
(_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* This function calls the profiling functions. */
|
||||
extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -1,4 +0,0 @@
|
||||
struct link_map_machine
|
||||
{
|
||||
/* empty by default */
|
||||
};
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/* Definitions for BSD-style memory management.
|
||||
Copyright (C) 1994-1998,2000,01,02 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* These are the bits used by 4.4 BSD and its derivatives. On systems
|
||||
(such as GNU) where these facilities are not system services but can be
|
||||
emulated in the C library, these are the definitions we emulate. */
|
||||
|
||||
#ifndef _SYS_MMAN_H
|
||||
# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
|
||||
#endif
|
||||
|
||||
/* Protections are chosen from these bits, OR'd together. The
|
||||
implementation does not necessarily support PROT_EXEC or PROT_WRITE
|
||||
without PROT_READ. The only guarantees are that no writing will be
|
||||
allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
|
||||
|
||||
#define PROT_NONE 0x00 /* No access. */
|
||||
#define PROT_READ 0x04 /* Pages can be read. */
|
||||
#define PROT_WRITE 0x02 /* Pages can be written. */
|
||||
#define PROT_EXEC 0x01 /* Pages can be executed. */
|
||||
|
||||
/* Flags contain mapping type, sharing type and options. */
|
||||
|
||||
/* Mapping type (must choose one and only one of these). */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_FILE 0x0001 /* Mapped from a file or device. */
|
||||
# define MAP_ANON 0x0002 /* Allocated from anonymous virtual memory. */
|
||||
# define MAP_TYPE 0x000f /* Mask for type field. */
|
||||
# ifdef __USE_MISC
|
||||
# define MAP_ANONYMOUS MAP_ANON /* Linux name. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Sharing types (must choose one and only one of these). */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_COPY 0x0020 /* Virtual copy of region at mapping time. */
|
||||
#endif
|
||||
#define MAP_SHARED 0x0010 /* Share changes. */
|
||||
#define MAP_PRIVATE 0x0000 /* Changes private; copy pages on write. */
|
||||
|
||||
/* Other flags. */
|
||||
#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_NOEXTEND 0x0200 /* For MAP_FILE, don't change file size. */
|
||||
# define MAP_HASSEMPHORE 0x0400 /* Region may contain semaphores. */
|
||||
# define MAP_INHERIT 0x0800 /* Region is retained after exec. */
|
||||
#endif
|
||||
|
||||
/* Advice to `madvise'. */
|
||||
#ifdef __USE_BSD
|
||||
# define MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
||||
|
||||
/* The POSIX people had to invent similar names for the same things. */
|
||||
#ifdef __USE_XOPEN2K
|
||||
# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
||||
|
||||
/* Flags to `msync'. */
|
||||
#define MS_ASYNC 1 /* Sync memory asynchronously. */
|
||||
#define MS_SYNC 0 /* Synchronous memory sync. */
|
||||
#define MS_INVALIDATE 2 /* Invalidate the caches. */
|
||||
|
||||
/* Flags for `mlockall' (can be OR'd together). */
|
||||
#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
|
||||
#define MCL_FUTURE 2 /* Lock all additions to address
|
||||
space. */
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
/* bits/types.h -- definitions of __*_t types underlying *_t types.
|
||||
Copyright (C) 2002, 2003 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/*
|
||||
* Never include this file directly; use <sys/types.h> instead.
|
||||
*/
|
||||
|
||||
#ifndef _BITS_TYPES_H
|
||||
#define _BITS_TYPES_H 1
|
||||
|
||||
#include <features.h>
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
/* Convenience types. */
|
||||
typedef unsigned char __u_char;
|
||||
typedef unsigned short int __u_short;
|
||||
typedef unsigned int __u_int;
|
||||
typedef unsigned long int __u_long;
|
||||
|
||||
/* Fixed-size types, underlying types depend on word size and compiler. */
|
||||
typedef signed char __int8_t;
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef signed short int __int16_t;
|
||||
typedef unsigned short int __uint16_t;
|
||||
typedef signed int __int32_t;
|
||||
typedef unsigned int __uint32_t;
|
||||
#if __WORDSIZE == 64
|
||||
typedef signed long int __int64_t;
|
||||
typedef unsigned long int __uint64_t;
|
||||
#elif defined __GLIBC_HAVE_LONG_LONG
|
||||
__extension__ typedef signed long long int __int64_t;
|
||||
__extension__ typedef unsigned long long int __uint64_t;
|
||||
#endif
|
||||
|
||||
/* quad_t is also 64 bits. */
|
||||
#if __WORDSIZE == 64
|
||||
typedef long int __quad_t;
|
||||
typedef unsigned long int __u_quad_t;
|
||||
#elif defined __GLIBC_HAVE_LONG_LONG
|
||||
__extension__ typedef long long int __quad_t;
|
||||
__extension__ typedef unsigned long long int __u_quad_t;
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
long __val[2];
|
||||
} __quad_t;
|
||||
typedef struct
|
||||
{
|
||||
__u_long __val[2];
|
||||
} __u_quad_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* The machine-dependent file <bits/typesizes.h> defines __*_T_TYPE
|
||||
macros for each of the OS types we define below. The definitions
|
||||
of those macros must use the following macros for underlying types.
|
||||
We define __S<SIZE>_TYPE and __U<SIZE>_TYPE for the signed and unsigned
|
||||
variants of each of the following integer types on this machine.
|
||||
|
||||
16 -- "natural" 16-bit type (always short)
|
||||
32 -- "natural" 32-bit type (always int)
|
||||
64 -- "natural" 64-bit type (long or long long)
|
||||
LONG32 -- 32-bit type, traditionally long
|
||||
QUAD -- 64-bit type, always long long
|
||||
WORD -- natural type of __WORDSIZE bits (int or long)
|
||||
LONGWORD -- type of __WORDSIZE bits, traditionally long
|
||||
|
||||
We distinguish WORD/LONGWORD, 32/LONG32, and 64/QUAD so that the
|
||||
conventional uses of `long' or `long long' type modifiers match the
|
||||
types we define, even when a less-adorned type would be the same size.
|
||||
This matters for (somewhat) portably writing printf/scanf formats for
|
||||
these types, where using the appropriate l or ll format modifiers can
|
||||
make the typedefs and the formats match up across all GNU platforms. If
|
||||
we used `long' when it's 64 bits where `long long' is expected, then the
|
||||
compiler would warn about the formats not matching the argument types,
|
||||
and the programmer changing them to shut up the compiler would break the
|
||||
program's portability.
|
||||
|
||||
Here we assume what is presently the case in all the GCC configurations
|
||||
we support: long long is always 64 bits, long is always word/address size,
|
||||
and int is always 32 bits. */
|
||||
|
||||
#define __S16_TYPE short int
|
||||
#define __U16_TYPE unsigned short int
|
||||
#define __S32_TYPE int
|
||||
#define __U32_TYPE unsigned int
|
||||
#define __SLONGWORD_TYPE long int
|
||||
#define __ULONGWORD_TYPE unsigned long int
|
||||
#if __WORDSIZE == 32
|
||||
# define __SQUAD_TYPE long long int
|
||||
# define __UQUAD_TYPE unsigned long long int
|
||||
# define __SWORD_TYPE int
|
||||
# define __UWORD_TYPE unsigned int
|
||||
# define __SLONG32_TYPE long int
|
||||
# define __ULONG32_TYPE unsigned long int
|
||||
# define __S64_TYPE __quad_t
|
||||
# define __U64_TYPE __u_quad_t
|
||||
#elif __WORDSIZE == 64
|
||||
# define __SQUAD_TYPE long int
|
||||
# define __UQUAD_TYPE unsigned long int
|
||||
# define __SWORD_TYPE long int
|
||||
# define __UWORD_TYPE unsigned long int
|
||||
# define __SLONG32_TYPE int
|
||||
# define __ULONG32_TYPE unsigned int
|
||||
# define __S64_TYPE long int
|
||||
# define __U64_TYPE unsigned long int
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
#include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */
|
||||
|
||||
/* We want __extension__ before typedef's that use nonstandard base types
|
||||
such as `long long' in C89 mode. */
|
||||
#define __STD_TYPE __extension__ typedef
|
||||
|
||||
|
||||
__STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */
|
||||
__STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */
|
||||
__STD_TYPE __GID_T_TYPE __gid_t; /* Type of group identifications. */
|
||||
__STD_TYPE __INO_T_TYPE __ino_t; /* Type of file serial numbers. */
|
||||
__STD_TYPE __INO64_T_TYPE __ino64_t; /* Type of file serial numbers (LFS).*/
|
||||
__STD_TYPE __MODE_T_TYPE __mode_t; /* Type of file attribute bitmasks. */
|
||||
__STD_TYPE __NLINK_T_TYPE __nlink_t; /* Type of file link counts. */
|
||||
__STD_TYPE __OFF_T_TYPE __off_t; /* Type of file sizes and offsets. */
|
||||
__STD_TYPE __OFF64_T_TYPE __off64_t; /* Type of file sizes and offsets (LFS). */
|
||||
__STD_TYPE __PID_T_TYPE __pid_t; /* Type of process identifications. */
|
||||
__STD_TYPE __FSID_T_TYPE __fsid_t; /* Type of file system IDs. */
|
||||
__STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */
|
||||
__STD_TYPE __RLIM_T_TYPE __rlim_t; /* Type for resource measurement. */
|
||||
__STD_TYPE __RLIM64_T_TYPE __rlim64_t; /* Type for resource measurement (LFS). */
|
||||
__STD_TYPE __ID_T_TYPE __id_t; /* General type for IDs. */
|
||||
__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
|
||||
__STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */
|
||||
__STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */
|
||||
|
||||
__STD_TYPE __DADDR_T_TYPE __daddr_t; /* The type of a disk address. */
|
||||
__STD_TYPE __SWBLK_T_TYPE __swblk_t; /* Type of a swap block maybe? */
|
||||
__STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */
|
||||
|
||||
/* Clock ID used in clock and timer functions. */
|
||||
__STD_TYPE __CLOCKID_T_TYPE __clockid_t;
|
||||
|
||||
/* Timer ID returned by `timer_create'. */
|
||||
__STD_TYPE __TIMER_T_TYPE __timer_t;
|
||||
|
||||
/* Type to represent block size. */
|
||||
__STD_TYPE __BLKSIZE_T_TYPE __blksize_t;
|
||||
|
||||
/* Types from the Large File Support interface. */
|
||||
|
||||
/* Type to count number of disk blocks. */
|
||||
__STD_TYPE __BLKCNT_T_TYPE __blkcnt_t;
|
||||
__STD_TYPE __BLKCNT64_T_TYPE __blkcnt64_t;
|
||||
|
||||
/* Type to count file system blocks. */
|
||||
__STD_TYPE __FSBLKCNT_T_TYPE __fsblkcnt_t;
|
||||
__STD_TYPE __FSBLKCNT64_T_TYPE __fsblkcnt64_t;
|
||||
|
||||
/* Type to count file system nodes. */
|
||||
__STD_TYPE __FSFILCNT_T_TYPE __fsfilcnt_t;
|
||||
__STD_TYPE __FSFILCNT64_T_TYPE __fsfilcnt64_t;
|
||||
|
||||
__STD_TYPE __SSIZE_T_TYPE __ssize_t; /* Type of a byte count, or error. */
|
||||
|
||||
/* These few don't really vary by system, they always correspond
|
||||
to one of the other defined types. */
|
||||
typedef __off64_t __loff_t; /* Type of file sizes and offsets (LFS). */
|
||||
typedef __quad_t *__qaddr_t;
|
||||
typedef char *__caddr_t;
|
||||
|
||||
/* Duplicates info from stdint.h but this is used in unistd.h. */
|
||||
__STD_TYPE __SWORD_TYPE __intptr_t;
|
||||
|
||||
/* Duplicate info from sys/socket.h. */
|
||||
__STD_TYPE __U32_TYPE __socklen_t;
|
||||
|
||||
|
||||
#undef __STD_TYPE
|
||||
|
||||
#endif /* bits/types.h */
|
||||
@@ -1,104 +0,0 @@
|
||||
/* Definitions of status bits for `wait' et al.
|
||||
Copyright (C) 1992, 1994, 1996, 1997, 2000 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _SYS_WAIT_H && !defined _STDLIB_H
|
||||
# error "Never include <bits/waitstatus.h> directly; use <sys/wait.h> instead."
|
||||
#endif
|
||||
|
||||
|
||||
/* Everything extant so far uses these same bits. */
|
||||
|
||||
|
||||
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
|
||||
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
|
||||
|
||||
/* If WIFSIGNALED(STATUS), the terminating signal. */
|
||||
#define __WTERMSIG(status) ((status) & 0x7f)
|
||||
|
||||
/* If WIFSTOPPED(STATUS), the signal that stopped the child. */
|
||||
#define __WSTOPSIG(status) __WEXITSTATUS(status)
|
||||
|
||||
/* Nonzero if STATUS indicates normal termination. */
|
||||
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
|
||||
|
||||
/* Nonzero if STATUS indicates termination by a signal. */
|
||||
#ifdef __GNUC__
|
||||
# define __WIFSIGNALED(status) \
|
||||
(__extension__ ({ int __status = (status); \
|
||||
!__WIFSTOPPED(__status) && !__WIFEXITED(__status); }))
|
||||
#else /* Not GCC. */
|
||||
# define __WIFSIGNALED(status) (!__WIFSTOPPED(status) && !__WIFEXITED(status))
|
||||
#endif /* GCC. */
|
||||
|
||||
/* Nonzero if STATUS indicates the child is stopped. */
|
||||
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
|
||||
|
||||
/* Nonzero if STATUS indicates the child dumped core. */
|
||||
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
|
||||
|
||||
/* Macros for constructing status values. */
|
||||
#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
|
||||
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
|
||||
#define __WCOREFLAG 0x80
|
||||
|
||||
|
||||
#ifdef __USE_BSD
|
||||
|
||||
# include <endian.h>
|
||||
|
||||
union wait
|
||||
{
|
||||
int w_status;
|
||||
struct
|
||||
{
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int __w_termsig:7; /* Terminating signal. */
|
||||
unsigned int __w_coredump:1; /* Set if dumped core. */
|
||||
unsigned int __w_retcode:8; /* Return code if exited normally. */
|
||||
unsigned int:16;
|
||||
# endif /* Little endian. */
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int:16;
|
||||
unsigned int __w_retcode:8;
|
||||
unsigned int __w_coredump:1;
|
||||
unsigned int __w_termsig:7;
|
||||
# endif /* Big endian. */
|
||||
} __wait_terminated;
|
||||
struct
|
||||
{
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
|
||||
unsigned int __w_stopsig:8; /* Stopping signal. */
|
||||
unsigned int:16;
|
||||
# endif /* Little endian. */
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int:16;
|
||||
unsigned int __w_stopsig:8; /* Stopping signal. */
|
||||
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
|
||||
# endif /* Big endian. */
|
||||
} __wait_stopped;
|
||||
};
|
||||
|
||||
# define w_termsig __wait_terminated.__w_termsig
|
||||
# define w_coredump __wait_terminated.__w_coredump
|
||||
# define w_retcode __wait_terminated.__w_retcode
|
||||
# define w_stopsig __wait_stopped.__w_stopsig
|
||||
# define w_stopval __wait_stopped.__w_stopval
|
||||
|
||||
#endif /* Use BSD. */
|
||||
@@ -0,0 +1 @@
|
||||
The C stubs add-on version 2.1.2.
|
||||
@@ -0,0 +1,482 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This 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.
|
||||
|
||||
This 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 this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@@ -0,0 +1,42 @@
|
||||
2001-08-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gconv_stubs.c (__gconv_lookup_alias): Remove.
|
||||
(__gconv_NOOP, __gconv_compare_alias, __gconv_release_cache,
|
||||
__gconv_release_step): New.
|
||||
|
||||
2001-06-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gconv_stubs.c (__gconv_lookup_alias): New.
|
||||
|
||||
2000-02-27 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* gconv_stubs.c: Return __gconv_OK for:
|
||||
__gconv_transform_ascii_internal
|
||||
__gconv_transform_ucs2little_internal
|
||||
__gconv_transform_utf16_internal
|
||||
__gconv_transform_utf8_internal
|
||||
__gconv_transform_ucs2_internal
|
||||
|
||||
2000-02-25 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* gconv_stubs.c: add __c_stubs_is_compiled_in so we can detect when
|
||||
the library is linked in.
|
||||
|
||||
Wed Dec 8 13:47:25 1999 Ivan Brunello <ivan.brunello@tiscalinet.it>
|
||||
|
||||
* Makefile (extra-objs): Changed stubs.o to gconv_stubs.o.
|
||||
|
||||
Sun Dec 5 11:32:17 1999 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* gconv_stubs.c: Renamed from stubs.c.
|
||||
Support glibc 2.1.x.
|
||||
|
||||
Mon Aug 23 16:42:05 1999 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* Banner: New.
|
||||
* COPYING.LIB: Likewise.
|
||||
* Makefile: Likewise.
|
||||
* README: Likewise.
|
||||
* configure: Likewise.
|
||||
* stubs.c: Likewise.
|
||||
* test-stdio.c: Likewise.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Copyright (C) 1999 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.
|
||||
|
||||
#
|
||||
# Sub-makefile for the C stub add-on library.
|
||||
#
|
||||
subdir := c_stubs
|
||||
|
||||
tests-static := test-stdio
|
||||
tests := $(tests-static)
|
||||
|
||||
libc_stubs-objs := gconv_stubs.o
|
||||
|
||||
install-lib := libc_stubs.a
|
||||
non-lib.a := libc_stubs.a
|
||||
|
||||
extra-objs := gconv_stubs.o libc_stubs.a
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
CPPFLAGS += -I../iconv
|
||||
|
||||
include ../Rules
|
||||
|
||||
$(objpfx)libc_stubs.a: $(addprefix $(objpfx), $(libc_stubs-objs))
|
||||
-rm -f $@
|
||||
$(CC) -nostdlib -nostartfiles -r -o $@ $^
|
||||
|
||||
lib: $(objpfx)libc_stubs.a
|
||||
|
||||
$(objpfx)test-stdio: $(objpfx)libc_stubs.a
|
||||
@@ -0,0 +1,8 @@
|
||||
This is a stub add-on library for the GNU C library version 2.1.2 and
|
||||
above. It is used to create the smaller static binaries by stubbing
|
||||
out the gconv related functions. The resulting binaries may not have
|
||||
all the functionalities.
|
||||
|
||||
H.J. Lu
|
||||
hjl@gnu.org
|
||||
12/05/1999
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This is only to keep the GNU C library configure mechanism happy.
|
||||
# This is a shell script fragment sourced by the main configure script.
|
||||
# We have nothing we need to add here.
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Provide gconv stub functions for the minimum static binaries.
|
||||
Copyright (C) 1999, 2001, 2003, 2004 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 <features.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#if __GNUC_PREREQ(3, 3)
|
||||
# include <gconv_int.h>
|
||||
#else
|
||||
# include <gconv.h>
|
||||
#endif
|
||||
|
||||
__libc_lock_define_initialized (, __gconv_lock)
|
||||
|
||||
/* hack for self identification */
|
||||
int __c_stubs_is_compiled_in;
|
||||
|
||||
/* Don't drag in the dynamic linker. */
|
||||
void *__libc_stack_end;
|
||||
|
||||
int attribute_hidden
|
||||
__gconv_OK (void)
|
||||
{
|
||||
#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
|
||||
return __GCONV_OK;
|
||||
#else
|
||||
return GCONV_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int attribute_hidden
|
||||
__gconv_NOCONV (void)
|
||||
{
|
||||
#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
|
||||
return __GCONV_NOCONV;
|
||||
#else
|
||||
return GCONV_NOCONV;
|
||||
#endif
|
||||
}
|
||||
|
||||
void attribute_hidden
|
||||
__gconv_NOOP (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
internal_function
|
||||
__gconv_compare_alias (const char *name1, const char *name2)
|
||||
{
|
||||
return strcmp (name1, name2);
|
||||
}
|
||||
|
||||
wint_t
|
||||
__gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c)
|
||||
{
|
||||
if (c < 0x80)
|
||||
return c;
|
||||
else
|
||||
return WEOF;
|
||||
}
|
||||
|
||||
|
||||
#if __GNUC_PREREQ(3, 3)
|
||||
# undef strong_alias
|
||||
# define strong_alias(impl, name) \
|
||||
__typeof (name) name __attribute__ ((alias (#impl)))
|
||||
#endif
|
||||
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_close_transform);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_close);
|
||||
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_find_transform);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_open);
|
||||
|
||||
/* These transformations should not fail in normal conditions */
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_ascii_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_utf16_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_utf8_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_ucs2_internal);
|
||||
|
||||
/* We can assume no conversion for these ones */
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ascii);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ucs2);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ucs4);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_utf16);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_utf8);
|
||||
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transliterate);
|
||||
|
||||
strong_alias (__gconv_NOOP,
|
||||
__gconv_release_cache);
|
||||
strong_alias (__gconv_NOOP,
|
||||
__gconv_release_step);
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
printf ("Hello world\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -5399,56 +5399,17 @@ echo $ECHO_N "checking for libunwind-support in compiler... $ECHO_C" >&6
|
||||
if test "${libc_cv_cc_with_libunwind+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <libunwind.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
unw_context_t uc;
|
||||
unw_cursor_t c;
|
||||
unw_getcontext (&uc);
|
||||
unw_init_local (&c, &uc)
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
libc_cv_cc_with_libunwind=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
libc_cv_cc_with_libunwind=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
cat > conftest.c <<EOF
|
||||
int main (void) { return 0; }
|
||||
EOF
|
||||
if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static -o conftest \
|
||||
conftest.c -v 2>&1 >/dev/null | grep -q " -lunwind "; then
|
||||
libc_cv_cc_with_libunwind=yes
|
||||
else
|
||||
libc_cv_cc_with_libunwind=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $libc_cv_cc_with_libunwind" >&5
|
||||
echo "${ECHO_T}$libc_cv_cc_with_libunwind" >&6
|
||||
@@ -6089,49 +6050,6 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
case "${host_cpu}-${host_os}" in
|
||||
cris*)
|
||||
libc_cv_asm_line_sep='@'
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ASM_LINE_SEP $libc_cv_asm_line_sep
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
hppa*linux*)
|
||||
echo "$as_me:$LINENO: checking for assembler line separator" >&5
|
||||
echo $ECHO_N "checking for assembler line separator... $ECHO_C" >&6
|
||||
if test "${libc_cv_asm_line_sep+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat > conftest.s <<EOF
|
||||
nop ; is_old_puffin
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
libc_cv_asm_line_sep='!'
|
||||
else
|
||||
if test -z "$enable_hacker_mode"; then
|
||||
echo "*** You need a newer assembler to compile glibc"
|
||||
rm -f conftest*
|
||||
exit 1
|
||||
fi
|
||||
libc_cv_asm_line_sep=';'
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $libc_cv_asm_line_sep" >&5
|
||||
echo "${ECHO_T}$libc_cv_asm_line_sep" >&6
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ASM_LINE_SEP $libc_cv_asm_line_sep
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$as_me:$LINENO: checking whether CFI directives are supported" >&5
|
||||
echo $ECHO_N "checking whether CFI directives are supported... $ECHO_C" >&6
|
||||
if test "${libc_cv_asm_cfi_directives+set}" = set; then
|
||||
@@ -6842,15 +6760,10 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
echo "${ECHO_T}$have_selinux" >&6
|
||||
fi
|
||||
|
||||
if test x$with_selinux = xauto ; then
|
||||
if test x$with_selinux = xyes ; then
|
||||
if test x$have_selinux = xno ; then
|
||||
{ echo "$as_me:$LINENO: WARNING: Sufficiently new SELinux library not found" >&5
|
||||
echo "$as_me: WARNING: Sufficiently new SELinux library not found" >&2;}
|
||||
fi
|
||||
else
|
||||
if test x$have_selinux = xno ; then
|
||||
{ { echo "$as_me:$LINENO: error: SELinux explicitly required, and SELinux library not found" >&5
|
||||
echo "$as_me: error: SELinux explicitly required, and SELinux library not found" >&2;}
|
||||
{ { echo "$as_me:$LINENO: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&5
|
||||
echo "$as_me: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
fi
|
||||
|
||||
+11
-36
@@ -1260,13 +1260,17 @@ EOF
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK(for libunwind-support in compiler,
|
||||
libc_cv_cc_with_libunwind, [dnl
|
||||
AC_TRY_LINK([#include <libunwind.h>], [
|
||||
unw_context_t uc;
|
||||
unw_cursor_t c;
|
||||
unw_getcontext (&uc);
|
||||
unw_init_local (&c, &uc)],
|
||||
libc_cv_cc_with_libunwind=yes, libc_cv_cc_with_libunwind=no)])
|
||||
libc_cv_cc_with_libunwind, [
|
||||
cat > conftest.c <<EOF
|
||||
int main (void) { return 0; }
|
||||
EOF
|
||||
if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static -o conftest \
|
||||
conftest.c -v 2>&1 >/dev/null | grep -q " -lunwind "; then
|
||||
libc_cv_cc_with_libunwind=yes
|
||||
else
|
||||
libc_cv_cc_with_libunwind=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
AC_SUBST(libc_cv_cc_with_libunwind)
|
||||
if test $libc_cv_cc_with_libunwind = yes; then
|
||||
AC_DEFINE(HAVE_CC_WITH_LIBUNWIND)
|
||||
@@ -1617,35 +1621,6 @@ elif test $libc_cv_asm_weakext_directive = yes; then
|
||||
AC_DEFINE(HAVE_ASM_WEAKEXT_DIRECTIVE)
|
||||
fi
|
||||
|
||||
dnl The standard hppa assembler uses `;' to start comments and `!'
|
||||
dnl as a line separator. CRIS uses `;' to start comments and `@' for
|
||||
dnl line separator.
|
||||
case "${host_cpu}-${host_os}" in
|
||||
cris*)
|
||||
libc_cv_asm_line_sep='@'
|
||||
AC_DEFINE_UNQUOTED(ASM_LINE_SEP, $libc_cv_asm_line_sep)
|
||||
;;
|
||||
hppa*linux*)
|
||||
AC_CACHE_CHECK(for assembler line separator,
|
||||
libc_cv_asm_line_sep, [dnl
|
||||
cat > conftest.s <<EOF
|
||||
nop ; is_old_puffin
|
||||
EOF
|
||||
if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
libc_cv_asm_line_sep='!'
|
||||
else
|
||||
if test -z "$enable_hacker_mode"; then
|
||||
echo "*** You need a newer assembler to compile glibc"
|
||||
rm -f conftest*
|
||||
exit 1
|
||||
fi
|
||||
libc_cv_asm_line_sep=';'
|
||||
fi
|
||||
rm -f conftest*])
|
||||
AC_DEFINE_UNQUOTED(ASM_LINE_SEP, $libc_cv_asm_line_sep)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CACHE_CHECK(whether CFI directives are supported, libc_cv_asm_cfi_directives, [dnl
|
||||
cat > conftest.s <<EOF
|
||||
.text
|
||||
|
||||
@@ -44,6 +44,24 @@ extern void (*__init_array_start []) (void) attribute_hidden;
|
||||
extern void (*__init_array_end []) (void) attribute_hidden;
|
||||
extern void (*__fini_array_start []) (void) attribute_hidden;
|
||||
extern void (*__fini_array_end []) (void) attribute_hidden;
|
||||
|
||||
# if defined HAVE_VISIBILITY_ATTRIBUTE \
|
||||
&& (defined SHARED || defined LIBC_NONSHARED)
|
||||
# define hidden_undef_2(x) #x
|
||||
# define hidden_undef_1(x) hidden_undef_2 (x)
|
||||
# define hidden_undef(x) \
|
||||
__asm (hidden_undef_1 (ASM_GLOBAL_DIRECTIVE) " " #x); \
|
||||
__asm (".hidden " #x);
|
||||
# else
|
||||
# define hidden_undef(x)
|
||||
# endif
|
||||
|
||||
hidden_undef (__preinit_array_start)
|
||||
hidden_undef (__preinit_array_end)
|
||||
hidden_undef (__init_array_start)
|
||||
hidden_undef (__init_array_end)
|
||||
hidden_undef (__fini_array_start)
|
||||
hidden_undef (__fini_array_end)
|
||||
#endif
|
||||
|
||||
/* These function symbols are provided for the .init/.fini section entry
|
||||
|
||||
+20
-4
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1998, 1999, 2000, 2001, 2004 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
|
||||
@@ -24,11 +24,26 @@ subdir := debug
|
||||
headers := execinfo.h
|
||||
distribute = sigcontextinfo.h register-dump.h frame.h
|
||||
|
||||
routines := backtrace backtracesyms backtracesymsfd noophooks
|
||||
routines := backtrace backtracesyms backtracesymsfd noophooks \
|
||||
memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
|
||||
strcat_chk strcpy_chk strncat_chk strncpy_chk \
|
||||
sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
|
||||
printf_chk fprintf_chk vprintf_chk vfprintf_chk \
|
||||
gets_chk chk_fail readonly-area
|
||||
|
||||
CFLAGS-backtrace.c = -fno-omit-frame-pointer
|
||||
CFLAGS-sprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-snprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-vsprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-vsnprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-printf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-fprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-vprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
|
||||
tests = backtrace-tst
|
||||
tests = backtrace-tst tst-chk1 tst-chk2 tst-chk3 \
|
||||
test-strcpy_chk test-stpcpy_chk
|
||||
|
||||
extra-libs = libSegFault libpcprofile
|
||||
extra-libs-others = $(extra-libs)
|
||||
@@ -57,7 +72,8 @@ include ../Rules
|
||||
|
||||
$(objpfx)catchsegv: catchsegv.sh $(common-objpfx)soversions.mk \
|
||||
$(common-objpfx)config.make
|
||||
sed -e 's|@VERSION@|$(version)|' -e 's|@SLIB@|$(slibdir)|' $< > $@.new
|
||||
slibpfx=`echo $(slibdir)|sed 's/lib\(64\|\)$$/\\\\\\\\$$LIB/'`; \
|
||||
sed -e 's|@VERSION@|$(version)|' -e "s|@SLIB@|$$slibpfx|" $< > $@.new
|
||||
chmod 555 $@.new
|
||||
mv -f $@.new $@
|
||||
|
||||
|
||||
@@ -10,4 +10,12 @@ libc {
|
||||
# These are to support some gcc features.
|
||||
__cyg_profile_func_enter; __cyg_profile_func_exit;
|
||||
}
|
||||
GLIBC_2.3.4 {
|
||||
__chk_fail;
|
||||
__memcpy_chk; __memmove_chk; __mempcpy_chk; __memset_chk; __stpcpy_chk;
|
||||
__strcat_chk; __strcpy_chk; __strncat_chk; __strncpy_chk;
|
||||
__sprintf_chk; __vsprintf_chk; __snprintf_chk; __vsnprintf_chk;
|
||||
__printf_chk; __fprintf_chk; __vprintf_chk; __vfprintf_chk;
|
||||
__gets_chk;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1998, 1999, 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
|
||||
@@ -39,7 +39,7 @@ if test $# -eq 0; then
|
||||
;;
|
||||
--v | --ve | --ver | --vers | --versi | --versio | --version)
|
||||
echo 'catchsegv (GNU libc) @VERSION@'
|
||||
echo 'Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
echo 'Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
Written by Ulrich Drepper.'
|
||||
@@ -50,9 +50,7 @@ Written by Ulrich Drepper.'
|
||||
esac
|
||||
fi
|
||||
|
||||
segv_output=`basename "$prog"`.segv.$$
|
||||
# Make sure this output file does not exist.
|
||||
rm -f "$segv_output"
|
||||
segv_output=`mktemp ${TMPDIR:-/tmp}/segv_output.XXXXXX` || exit
|
||||
|
||||
# Redirect stderr to avoid termination message from shell.
|
||||
(exec 3>&2 2>/dev/null
|
||||
@@ -65,7 +63,7 @@ exval=$?
|
||||
# Check for output. Even if the program terminated correctly it might
|
||||
# be that a minor process (clone) failed. Therefore we do not check the
|
||||
# exit code.
|
||||
if test -f "$segv_output"; then
|
||||
if test -s "$segv_output"; then
|
||||
# The program caught a signal. The output is in the file with the
|
||||
# name we have in SEGFAULT_OUTPUT_NAME. In the output the names of
|
||||
# functions in shared objects are available, but names in the static
|
||||
@@ -102,7 +100,7 @@ if test -f "$segv_output"; then
|
||||
;;
|
||||
esac
|
||||
done)
|
||||
rm -f "$segv_output"
|
||||
fi
|
||||
rm -f "$segv_output"
|
||||
|
||||
exit $exval
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
/* Copyright (C) 2004 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
|
||||
@@ -16,14 +17,14 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* We define only thr alias introduced in ISO C99 because _exit itself
|
||||
is a system call. */
|
||||
void
|
||||
_Exit (status)
|
||||
int status;
|
||||
__attribute__ ((noreturn))
|
||||
__chk_fail (void)
|
||||
{
|
||||
_exit (status);
|
||||
__libc_fatal ("*** buffer overflow detected ***\n");
|
||||
}
|
||||
libc_hidden_def (__chk_fail)
|
||||
+1
-1
@@ -25,7 +25,7 @@ __BEGIN_DECLS
|
||||
|
||||
/* Store up to SIZE return address of the current program state in
|
||||
ARRAY and return the exact number of values stored. */
|
||||
extern int backtrace (void **__array, int __size) __THROW __nonnull ((1));
|
||||
extern int backtrace (void **__array, int __size) __nonnull ((1));
|
||||
|
||||
|
||||
/* Return names of functions from the backtrace list in ARRAY in a newly
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
|
||||
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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
|
||||
/* Write formatted output to FP from the format string FORMAT. */
|
||||
int
|
||||
__fprintf_chk (FILE *fp, int flag, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int done;
|
||||
|
||||
_IO_acquire_lock (fp);
|
||||
if (flag > 0)
|
||||
fp->_flags2 |= _IO_FLAGS2_FORTIFY;
|
||||
|
||||
va_start (ap, format);
|
||||
done = vfprintf (fp, format, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (flag > 0)
|
||||
fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
|
||||
_IO_release_lock (fp);
|
||||
|
||||
return done;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* Copyright (C) 1993, 1996, 1997, 1998, 2002, 2003, 2004
|
||||
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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link the code in this file with
|
||||
files compiled with a GNU compiler to produce an executable,
|
||||
that does not cause the resulting executable to be covered by
|
||||
the GNU Lesser General Public License. This exception does not
|
||||
however invalidate any other reasons why the executable file
|
||||
might be covered by the GNU Lesser General Public License.
|
||||
This exception applies to code released by its copyright holders
|
||||
in files containing the exception. */
|
||||
|
||||
#include "../libio/libioP.h"
|
||||
#include <limits.h>
|
||||
|
||||
char *
|
||||
__gets_chk (char *buf, size_t size)
|
||||
{
|
||||
_IO_size_t count;
|
||||
int ch;
|
||||
char *retval;
|
||||
|
||||
if (size == 0)
|
||||
__chk_fail ();
|
||||
|
||||
_IO_acquire_lock (_IO_stdin);
|
||||
ch = _IO_getc_unlocked (_IO_stdin);
|
||||
if (ch == EOF)
|
||||
{
|
||||
retval = NULL;
|
||||
goto unlock_return;
|
||||
}
|
||||
if (ch == '\n')
|
||||
count = 0;
|
||||
else
|
||||
{
|
||||
/* This is very tricky since a file descriptor may be in the
|
||||
non-blocking mode. The error flag doesn't mean much in this
|
||||
case. We return an error only when there is a new error. */
|
||||
int old_error = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN;
|
||||
_IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN;
|
||||
buf[0] = (char) ch;
|
||||
count = INTUSE(_IO_getline) (_IO_stdin, buf + 1, size - 1, '\n', 0) + 1;
|
||||
if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN)
|
||||
{
|
||||
retval = NULL;
|
||||
goto unlock_return;
|
||||
}
|
||||
else
|
||||
_IO_stdin->_IO_file_flags |= old_error;
|
||||
}
|
||||
if (count >= size)
|
||||
__chk_fail ();
|
||||
buf[count] = 0;
|
||||
retval = buf;
|
||||
unlock_return:
|
||||
_IO_release_lock (_IO_stdin);
|
||||
return retval;
|
||||
}
|
||||
|
||||
link_warning (__gets_chk, "the `gets' function is dangerous and should not be used.")
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
|
||||
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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
|
||||
/* Write formatted output to stdout from the format string FORMAT. */
|
||||
int
|
||||
__printf_chk (int flag, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int done;
|
||||
|
||||
_IO_acquire_lock (stdout);
|
||||
if (flag > 0)
|
||||
stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
|
||||
|
||||
va_start (ap, format);
|
||||
done = vfprintf (stdout, format, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (flag > 0)
|
||||
stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
|
||||
_IO_release_lock (stdout);
|
||||
|
||||
return done;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1995, 1997, 1998, 2004 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
|
||||
@@ -16,25 +16,23 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Write formatted output into S, according to the format
|
||||
string FORMAT, writing no more than MAXLEN characters. */
|
||||
/* VARARGS5 */
|
||||
int
|
||||
__open (const char *file, int oflag, ...)
|
||||
__snprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
|
||||
const char *format, ...)
|
||||
{
|
||||
int mode = 0;
|
||||
va_list arg;
|
||||
int done;
|
||||
|
||||
if (oflag & O_CREAT)
|
||||
{
|
||||
va_list arg;
|
||||
va_start (arg, oflag);
|
||||
mode = va_arg (arg, int);
|
||||
va_end (arg);
|
||||
}
|
||||
va_start (arg, format);
|
||||
done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg);
|
||||
va_end (arg);
|
||||
|
||||
return open (file, oflag, mode);
|
||||
return done;
|
||||
}
|
||||
libc_hidden_def (__open)
|
||||
strong_alias (__open, __libc_open)
|
||||
libc_hidden_def (__libc_open)
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991,1995,1997,1998,2002,2004 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
|
||||
@@ -17,21 +17,19 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <sys/resource.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long int
|
||||
__ulimit (int cmd, ...)
|
||||
/* Write formatted output into S, according to the format string FORMAT. */
|
||||
/* VARARGS4 */
|
||||
int
|
||||
__sprintf_chk (char *s, int flags, size_t slen, const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
long int arg;
|
||||
long int res;
|
||||
va_list arg;
|
||||
int done;
|
||||
|
||||
va_start (va, cmd);
|
||||
arg = va_arg (va, long int);
|
||||
va_start (arg, format);
|
||||
done = __vsprintf_chk (s, flags, slen, format, arg);
|
||||
va_end (arg);
|
||||
|
||||
res = ulimit (cmd, arg);
|
||||
|
||||
va_end (va);
|
||||
|
||||
return res;
|
||||
return done;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/* Test and measure stpcpy checking functions.
|
||||
Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define STRCPY_RESULT(dst, len) ((dst) + (len))
|
||||
#define TEST_MAIN
|
||||
#include "../string/test-string.h"
|
||||
|
||||
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||
char *simple_stpcpy_chk (char *, const char *, size_t);
|
||||
extern char *normal_stpcpy (char *, const char *, size_t)
|
||||
__asm ("stpcpy");
|
||||
extern char *__stpcpy_chk (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_stpcpy_chk, 0)
|
||||
IMPL (normal_stpcpy, 1)
|
||||
IMPL (__stpcpy_chk, 2)
|
||||
|
||||
char *
|
||||
simple_stpcpy_chk (char *dst, const char *src, size_t len)
|
||||
{
|
||||
if (! len)
|
||||
__chk_fail ();
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
if (--len == 0)
|
||||
__chk_fail ();
|
||||
return dst - 1;
|
||||
}
|
||||
|
||||
#include "test-strcpy_chk.c"
|
||||
@@ -0,0 +1,387 @@
|
||||
/* Test and measure __strcpy_chk functions.
|
||||
Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef STRCPY_RESULT
|
||||
# define STRCPY_RESULT(dst, len) dst
|
||||
# define TEST_MAIN
|
||||
# include "../string/test-string.h"
|
||||
|
||||
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||
char *simple_strcpy_chk (char *, const char *, size_t);
|
||||
extern char *normal_strcpy (char *, const char *, size_t)
|
||||
__asm ("strcpy");
|
||||
extern char *__strcpy_chk (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_strcpy_chk, 0)
|
||||
IMPL (normal_strcpy, 1)
|
||||
IMPL (__strcpy_chk, 2)
|
||||
|
||||
char *
|
||||
simple_strcpy_chk (char *dst, const char *src, size_t len)
|
||||
{
|
||||
char *ret = dst;
|
||||
if (! len)
|
||||
__chk_fail ();
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
if (--len == 0)
|
||||
__chk_fail ();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
volatile int chk_fail_ok;
|
||||
jmp_buf chk_fail_buf;
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
if (chk_fail_ok)
|
||||
{
|
||||
chk_fail_ok = 0;
|
||||
longjmp (chk_fail_buf, 1);
|
||||
}
|
||||
else
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
size_t len, size_t dlen)
|
||||
{
|
||||
char *res;
|
||||
if (dlen <= len)
|
||||
{
|
||||
if (impl->test == 1)
|
||||
return;
|
||||
|
||||
chk_fail_ok = 1;
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
|
||||
impl->name, len, dlen);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
|
||||
if (res != STRCPY_RESULT (dst, len))
|
||||
{
|
||||
printf ("Wrong result in function %s %p %p\n", impl->name,
|
||||
res, STRCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (dst, src) != 0)
|
||||
{
|
||||
printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));;
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, dlen);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL && dlen > len)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len, dlen);
|
||||
|
||||
if (HP_TIMING_AVAIL && dlen > len)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
do_random_tests (void)
|
||||
{
|
||||
size_t i, j, n, align1, align2, len, dlen;
|
||||
unsigned char *p1 = buf1 + page_size - 512;
|
||||
unsigned char *p2 = buf2 + page_size - 512;
|
||||
unsigned char *res;
|
||||
|
||||
for (n = 0; n < ITERATIONS; n++)
|
||||
{
|
||||
align1 = random () & 31;
|
||||
if (random () & 1)
|
||||
align2 = random () & 31;
|
||||
else
|
||||
align2 = align1 + (random () & 24);
|
||||
len = random () & 511;
|
||||
j = align1;
|
||||
if (align2 > j)
|
||||
j = align2;
|
||||
if (len + j >= 511)
|
||||
len = 510 - j - (random () & 7);
|
||||
j = len + align1 + 64;
|
||||
if (j > 512)
|
||||
j = 512;
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (i == len + align1)
|
||||
p1[i] = 0;
|
||||
else
|
||||
{
|
||||
p1[i] = random () & 255;
|
||||
if (i >= align1 && i < len + align1 && !p1[i])
|
||||
p1[i] = (random () & 127) + 3;
|
||||
}
|
||||
}
|
||||
|
||||
switch (random () & 7)
|
||||
{
|
||||
case 0:
|
||||
dlen = len - (random () & 31);
|
||||
if (dlen > len)
|
||||
dlen = len;
|
||||
break;
|
||||
case 1:
|
||||
dlen = (size_t) -1;
|
||||
break;
|
||||
case 2:
|
||||
dlen = len + 1 + (random () & 65535);
|
||||
break;
|
||||
case 3:
|
||||
dlen = len + 1 + (random () & 255);
|
||||
break;
|
||||
case 4:
|
||||
dlen = len + 1 + (random () & 31);
|
||||
break;
|
||||
case 5:
|
||||
dlen = len + 1 + (random () & 7);
|
||||
break;
|
||||
case 6:
|
||||
dlen = len + 1 + (random () & 3);
|
||||
break;
|
||||
default:
|
||||
dlen = len + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
if (dlen <= len)
|
||||
{
|
||||
if (impl->test != 1)
|
||||
{
|
||||
chk_fail_ok = 1;
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, p2 + align2, p1 + align1, dlen);
|
||||
printf ("Iteration %zd - did not __chk_fail\n", n);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
memset (p2 - 64, '\1', 512 + 64);
|
||||
res = CALL (impl, p2 + align2, p1 + align1, dlen);
|
||||
if (res != STRCPY_RESULT (p2 + align2, len))
|
||||
{
|
||||
printf ("\
|
||||
Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n",
|
||||
n, impl->name, align1, align2, len, res,
|
||||
STRCPY_RESULT (p2 + align2, len));
|
||||
ret = 1;
|
||||
}
|
||||
for (j = 0; j < align2 + 64; ++j)
|
||||
{
|
||||
if (p2[j - 64] != '\1')
|
||||
{
|
||||
printf ("\
|
||||
Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j = align2 + len + 1; j < 512; ++j)
|
||||
{
|
||||
if (p2[j] != '\1')
|
||||
{
|
||||
printf ("\
|
||||
Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memcmp (p1 + align1, p2 + align2, len + 1))
|
||||
{
|
||||
printf ("\
|
||||
Iteration %zd - different strings, %s (%zd, %zd, %zd)\n",
|
||||
n, impl->name, align1, align2, len);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
/* Avoid all the buffer overflow messages on stderr. */
|
||||
int fd = open (_PATH_DEVNULL, O_WRONLY);
|
||||
if (fd == -1)
|
||||
close (STDERR_FILENO);
|
||||
else
|
||||
{
|
||||
dup2 (fd, STDERR_FILENO);
|
||||
close (fd);
|
||||
}
|
||||
setenv ("LIBC_FATAL_STDERR_", "1", 1);
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i + 1, 127);
|
||||
do_test (0, 0, i, i + 1, 255);
|
||||
do_test (0, i, i, i + 1, 127);
|
||||
do_test (i, 0, i, i + 1, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) + 1, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + 1, 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + 1, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + 1, 255);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i + 256, 127);
|
||||
do_test (0, 0, i, i + 256, 255);
|
||||
do_test (0, i, i, i + 256, 127);
|
||||
do_test (i, 0, i, i + 256, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) + 256, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + 256, 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + 256, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + 256, 255);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i, 127);
|
||||
do_test (0, 0, i, i + 2, 255);
|
||||
do_test (0, i, i, i + 3, 127);
|
||||
do_test (i, 0, i, i + 4, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) - 15, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + i, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + i + 2, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + i + 3, 255);
|
||||
}
|
||||
|
||||
do_random_tests ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,495 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char *temp_filename;
|
||||
static void do_prepare (void);
|
||||
static int do_test (void);
|
||||
#define PREPARE(argc, argv) do_prepare ()
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static void
|
||||
do_prepare (void)
|
||||
{
|
||||
int temp_fd = create_temp_file ("tst-chk1.", &temp_filename);
|
||||
if (temp_fd == -1)
|
||||
{
|
||||
printf ("cannot create temporary file: %m\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
|
||||
if (write (temp_fd, strs, strlen (strs)) != strlen (strs))
|
||||
{
|
||||
puts ("could not write test strings into file");
|
||||
unlink (temp_filename);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
volatile int chk_fail_ok;
|
||||
volatile int ret;
|
||||
jmp_buf chk_fail_buf;
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
if (chk_fail_ok)
|
||||
{
|
||||
chk_fail_ok = 0;
|
||||
longjmp (chk_fail_buf, 1);
|
||||
}
|
||||
else
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
char buf[10];
|
||||
volatile size_t l0;
|
||||
volatile char *p;
|
||||
const char *str1 = "JIHGFEDCBA";
|
||||
const char *str2 = "F";
|
||||
const char *str3 = "%s%n%s%n";
|
||||
const char *str4 = "Hello, ";
|
||||
const char *str5 = "World!\n";
|
||||
char buf2[10] = "%s";
|
||||
int num1 = 67;
|
||||
int num2 = 987654;
|
||||
|
||||
#define FAIL() \
|
||||
do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
|
||||
#define CHK_FAIL_START \
|
||||
chk_fail_ok = 1; \
|
||||
if (! setjmp (chk_fail_buf)) \
|
||||
{
|
||||
#define CHK_FAIL_END \
|
||||
chk_fail_ok = 0; \
|
||||
FAIL (); \
|
||||
}
|
||||
#if __USE_FORTIFY_LEVEL >= 2
|
||||
#define CHK_FAIL2_START CHK_FAIL_START
|
||||
#define CHK_FAIL2_END CHK_FAIL_END
|
||||
#else
|
||||
#define CHK_FAIL2_START
|
||||
#define CHK_FAIL2_END
|
||||
#endif
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
/* Avoid all the buffer overflow messages on stderr. */
|
||||
int fd = open (_PATH_DEVNULL, O_WRONLY);
|
||||
if (fd == -1)
|
||||
close (STDERR_FILENO);
|
||||
else
|
||||
{
|
||||
dup2 (fd, STDERR_FILENO);
|
||||
close (fd);
|
||||
}
|
||||
setenv ("LIBC_FATAL_STDERR_", "1", 1);
|
||||
|
||||
struct A { char buf1[9]; char buf2[1]; } a;
|
||||
|
||||
printf ("Test checking routines at fortify level %d\n",
|
||||
#ifdef __USE_FORTIFY_LEVEL
|
||||
(int) __USE_FORTIFY_LEVEL
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
|
||||
/* These ops can be done without runtime checking of object size. */
|
||||
memcpy (buf, "abcdefghij", 10);
|
||||
memmove (buf + 1, buf, 9);
|
||||
if (memcmp (buf, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
memset (buf + 8, 'j', 2);
|
||||
if (memcmp (buf, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf + 4, "EDCBA");
|
||||
if (memcmp (buf, "aabcEDCBA", 10))
|
||||
FAIL ();
|
||||
|
||||
if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
|
||||
FAIL ();
|
||||
|
||||
strncpy (buf + 6, "X", 4);
|
||||
if (memcmp (buf, "aabcEDX\0\0", 10))
|
||||
FAIL ();
|
||||
|
||||
if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10))
|
||||
FAIL ();
|
||||
|
||||
if (snprintf (buf + 7, 3, "%s", "987654") != 6
|
||||
|| memcmp (buf, "aabcEDX98", 10))
|
||||
FAIL ();
|
||||
|
||||
/* These ops need runtime checking, but shouldn't __chk_fail. */
|
||||
memcpy (buf, "abcdefghij", l0 + 10);
|
||||
memmove (buf + 1, buf, l0 + 9);
|
||||
if (memcmp (buf, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
memset (buf + 8, 'j', l0 + 2);
|
||||
if (memcmp (buf, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf + 4, str1 + 5);
|
||||
if (memcmp (buf, "aabcEDCBA", 10))
|
||||
FAIL ();
|
||||
|
||||
if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
|
||||
FAIL ();
|
||||
|
||||
strncpy (buf + 6, "X", l0 + 4);
|
||||
if (memcmp (buf, "aabcEDX\0\0", 10))
|
||||
FAIL ();
|
||||
|
||||
if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEDX67", 10))
|
||||
FAIL ();
|
||||
|
||||
if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10))
|
||||
FAIL ();
|
||||
|
||||
buf[l0 + 8] = '\0';
|
||||
strcat (buf, "A");
|
||||
if (memcmp (buf, "aabcEDX9A", 10))
|
||||
FAIL ();
|
||||
|
||||
buf[l0 + 7] = '\0';
|
||||
strncat (buf, "ZYXWV", l0 + 2);
|
||||
if (memcmp (buf, "aabcEDXZY", 10))
|
||||
FAIL ();
|
||||
|
||||
memcpy (a.buf1, "abcdefghij", l0 + 10);
|
||||
memmove (a.buf1 + 1, a.buf1, l0 + 9);
|
||||
if (memcmp (a.buf1, "aabcdefghi", 10))
|
||||
FAIL ();
|
||||
|
||||
if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
|
||||
|| memcmp (a.buf1, "aabcdabcde", 10))
|
||||
FAIL ();
|
||||
|
||||
memset (a.buf1 + 8, 'j', l0 + 2);
|
||||
if (memcmp (a.buf1, "aabcdabcjj", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0)
|
||||
/* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
|
||||
and sufficient GCC support, as the string operations overflow
|
||||
from a.buf1 into a.buf2. */
|
||||
strcpy (a.buf1 + 4, str1 + 5);
|
||||
if (memcmp (a.buf1, "aabcEDCBA", 10))
|
||||
FAIL ();
|
||||
|
||||
if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10))
|
||||
FAIL ();
|
||||
|
||||
strncpy (a.buf1 + 6, "X", l0 + 4);
|
||||
if (memcmp (a.buf1, "aabcEDX\0\0", 10))
|
||||
FAIL ();
|
||||
|
||||
if (sprintf (a.buf1 + 7, "%d", num1) != 2 || memcmp (a.buf1, "aabcEDX67", 10))
|
||||
FAIL ();
|
||||
|
||||
if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
|
||||
|| memcmp (a.buf1, "aabcEDX98", 10))
|
||||
FAIL ();
|
||||
|
||||
a.buf1[l0 + 8] = '\0';
|
||||
strcat (a.buf1, "A");
|
||||
if (memcmp (a.buf1, "aabcEDX9A", 10))
|
||||
FAIL ();
|
||||
|
||||
a.buf1[l0 + 7] = '\0';
|
||||
strncat (a.buf1, "ZYXWV", l0 + 2);
|
||||
if (memcmp (a.buf1, "aabcEDXZY", 10))
|
||||
FAIL ();
|
||||
|
||||
#endif
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
/* Now check if all buffer overflows are caught at runtime. */
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (buf + 1, "abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (buf + 2, buf + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = mempcpy (buf + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (buf + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strcpy (buf + 5, str1 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = stpcpy (buf + 9, str2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (buf + 7, "X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
sprintf (buf + 8, "%d", num1);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (buf + 8, l0 + 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (buf, str1 + 2, l0 + 9);
|
||||
CHK_FAIL_START
|
||||
strcat (buf, "AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (buf, str1 + 3, l0 + 8);
|
||||
CHK_FAIL_START
|
||||
strncat (buf, "ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memcpy (a.buf1 + 1, "abcdefghij", l0 + 10);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = mempcpy (a.buf1 + 6, "abcde", l0 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
memset (a.buf1 + 9, 'j', l0 + 2);
|
||||
CHK_FAIL_END
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0)
|
||||
# define O 0
|
||||
#else
|
||||
# define O 1
|
||||
#endif
|
||||
|
||||
CHK_FAIL_START
|
||||
strcpy (a.buf1 + (O + 4), str1 + 5);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
p = stpcpy (a.buf1 + (O + 8), str2);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
strncpy (a.buf1 + (O + 6), "X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
sprintf (a.buf1 + (O + 7), "%d", num1);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
|
||||
CHK_FAIL_START
|
||||
strcat (a.buf1, "AB");
|
||||
CHK_FAIL_END
|
||||
|
||||
memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O);
|
||||
CHK_FAIL_START
|
||||
strncat (a.buf1, "ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
/* Now checks for %n protection. */
|
||||
|
||||
/* Constant literals passed directly are always ok
|
||||
(even with warnings about possible bugs from GCC). */
|
||||
int n1, n2;
|
||||
if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2
|
||||
|| n1 != 1 || n2 != 2)
|
||||
FAIL ();
|
||||
|
||||
/* In this case the format string is not known at compile time,
|
||||
but resides in read-only memory, so is ok. */
|
||||
if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2
|
||||
|| n1 != 1 || n2 != 2)
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
|
||||
CHK_FAIL2_START
|
||||
if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
CHK_FAIL2_START
|
||||
if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
/* But if there is no %n, even writable format string
|
||||
should work. */
|
||||
buf2[6] = '\0';
|
||||
if (sprintf (buf, buf2 + 4, str2) != 1)
|
||||
FAIL ();
|
||||
|
||||
/* Constant literals passed directly are always ok
|
||||
(even with warnings about possible bugs from GCC). */
|
||||
if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
/* In this case the format string is not known at compile time,
|
||||
but resides in read-only memory, so is ok. */
|
||||
if (printf (str3, str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
|
||||
CHK_FAIL2_START
|
||||
if (printf (buf2, str4, &n1, str5, &n1) != 14)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
/* But if there is no %n, even writable format string
|
||||
should work. */
|
||||
buf2[6] = '\0';
|
||||
if (printf (buf2 + 4, str5) != 7)
|
||||
FAIL ();
|
||||
|
||||
FILE *fp = stdout;
|
||||
|
||||
/* Constant literals passed directly are always ok
|
||||
(even with warnings about possible bugs from GCC). */
|
||||
if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
/* In this case the format string is not known at compile time,
|
||||
but resides in read-only memory, so is ok. */
|
||||
if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14
|
||||
|| n1 != 7 || n2 != 14)
|
||||
FAIL ();
|
||||
|
||||
strcpy (buf2 + 2, "%n%s%n");
|
||||
/* When the format string is writable and contains %n,
|
||||
with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
|
||||
CHK_FAIL2_START
|
||||
if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14)
|
||||
FAIL ();
|
||||
CHK_FAIL2_END
|
||||
|
||||
/* But if there is no %n, even writable format string
|
||||
should work. */
|
||||
buf2[6] = '\0';
|
||||
if (fprintf (fp, buf2 + 4, str5) != 7)
|
||||
FAIL ();
|
||||
|
||||
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||
{
|
||||
puts ("could not open temporary file");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
|
||||
FAIL ();
|
||||
if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
if (gets (buf) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||
{
|
||||
puts ("could not open temporary file");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (fseek (stdin, 9 + 10 + 11, SEEK_SET))
|
||||
{
|
||||
puts ("could not seek in test file");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
if (gets (buf) != buf)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
/* Check whether missing N$ formats are detected. */
|
||||
CHK_FAIL2_START
|
||||
printf ("%3$d\n", 1, 2, 3, 4);
|
||||
CHK_FAIL2_END
|
||||
|
||||
CHK_FAIL2_START
|
||||
fprintf (stdout, "%3$d\n", 1, 2, 3, 4);
|
||||
CHK_FAIL2_END
|
||||
|
||||
CHK_FAIL2_START
|
||||
sprintf (buf, "%3$d\n", 1, 2, 3, 4);
|
||||
CHK_FAIL2_END
|
||||
|
||||
CHK_FAIL2_START
|
||||
snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
|
||||
CHK_FAIL2_END
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#define _FORTIFY_SOURCE 1
|
||||
#include "tst-chk1.c"
|
||||
@@ -0,0 +1,2 @@
|
||||
#define _FORTIFY_SOURCE 2
|
||||
#include "tst-chk1.c"
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
|
||||
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
|
||||
@@ -16,28 +17,26 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
extern int kfcntl (int fdes, int cmd, unsigned long int arg);
|
||||
|
||||
/* Write formatted output to FP from the format string FORMAT. */
|
||||
int
|
||||
__fcntl (int fdes, int cmd, ...)
|
||||
__vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap)
|
||||
{
|
||||
va_list va;
|
||||
int res;
|
||||
unsigned long int arg;
|
||||
int done;
|
||||
|
||||
va_start (va, cmd);
|
||||
arg = va_arg (va, unsigned long int);
|
||||
_IO_acquire_lock (fp);
|
||||
if (flag > 0)
|
||||
fp->_flags2 |= _IO_FLAGS2_FORTIFY;
|
||||
|
||||
res = kfcntl (fdes, cmd, arg);
|
||||
done = vfprintf (fp, format, ap);
|
||||
|
||||
va_end (va);
|
||||
if (flag > 0)
|
||||
fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
|
||||
_IO_release_lock (fp);
|
||||
|
||||
return res;
|
||||
return done;
|
||||
}
|
||||
libc_hidden_def (__fcntl)
|
||||
strong_alias (__fcntl, fcntl)
|
||||
strong_alias (__fcntl, __libc_fcntl)
|
||||
libc_hidden_def (__libc_fcntl)
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
|
||||
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
|
||||
@@ -17,27 +18,25 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
|
||||
extern int kioctl (int fdes, int cmd, unsigned long int arg,
|
||||
unsigned long int ext);
|
||||
|
||||
/* Write formatted output to stdout from the format string FORMAT. */
|
||||
int
|
||||
__ioctl (int fdes, unsigned long int cmd, ...)
|
||||
__vprintf_chk (int flag, const char *format, va_list ap)
|
||||
{
|
||||
va_list va;
|
||||
int res;
|
||||
unsigned long int arg;
|
||||
unsigned long int ext;
|
||||
int done;
|
||||
|
||||
va_start (va, cmd);
|
||||
arg = va_arg (va, unsigned long int);
|
||||
ext = va_arg (va, unsigned long int);
|
||||
_IO_acquire_lock (stdout);
|
||||
if (flag > 0)
|
||||
stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
|
||||
|
||||
res = kioctl (fdes, cmd, arg, ext);
|
||||
done = vfprintf (stdout, format, ap);
|
||||
|
||||
va_end (va);
|
||||
if (flag > 0)
|
||||
stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
|
||||
_IO_release_lock (stdout);
|
||||
|
||||
return res;
|
||||
return done;
|
||||
}
|
||||
strong_alias (__ioctl, ioctl)
|
||||
@@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 1991, 1995, 1997, 1998, 2004 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
#include "../libio/strfile.h"
|
||||
|
||||
extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
|
||||
|
||||
/* Write formatted output into S, according to the format
|
||||
string FORMAT, writing no more than MAXLEN characters. */
|
||||
/* VARARGS5 */
|
||||
int
|
||||
__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
|
||||
const char *format, va_list args)
|
||||
{
|
||||
/* XXX Maybe for less strict version do not fail immediately.
|
||||
Though, maxlen is supposed to be the size of buffer pointed
|
||||
to by s, so a conforming program can't pass such maxlen
|
||||
to *snprintf. */
|
||||
if (__builtin_expect (slen < maxlen, 0))
|
||||
__chk_fail ();
|
||||
|
||||
_IO_strnfile sf;
|
||||
int ret;
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
sf.f._sbf._f._lock = NULL;
|
||||
#endif
|
||||
|
||||
/* We need to handle the special case where MAXLEN is 0. Use the
|
||||
overflow buffer right from the start. */
|
||||
if (maxlen == 0)
|
||||
{
|
||||
s = sf.overflow_buf;
|
||||
maxlen = sizeof (sf.overflow_buf);
|
||||
}
|
||||
|
||||
_IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
|
||||
_IO_JUMPS ((struct _IO_FILE_plus *) &sf.f._sbf) = &_IO_strn_jumps;
|
||||
s[0] = '\0';
|
||||
|
||||
/* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
|
||||
can only come from read-only format strings. */
|
||||
if (flags > 0)
|
||||
sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY;
|
||||
|
||||
_IO_str_init_static_internal (&sf.f, s, maxlen - 1, s);
|
||||
ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf.f._sbf, format, args);
|
||||
|
||||
if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
|
||||
*sf.f._sbf._f._IO_write_ptr = '\0';
|
||||
return ret;
|
||||
}
|
||||
libc_hidden_def (__vsnprintf_chk)
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Copyright (C) 1994, 1997, 1999-2003, 2004 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "../libio/libioP.h"
|
||||
#include "../libio/strfile.h"
|
||||
|
||||
|
||||
static int _IO_str_chk_overflow (_IO_FILE *fp, int c) __THROW;
|
||||
|
||||
static int
|
||||
_IO_str_chk_overflow (fp, c)
|
||||
_IO_FILE *fp;
|
||||
int c;
|
||||
{
|
||||
/* When we come to here this means the user supplied buffer is
|
||||
filled. */
|
||||
__chk_fail ();
|
||||
}
|
||||
|
||||
|
||||
static const struct _IO_jump_t _IO_str_chk_jumps =
|
||||
{
|
||||
JUMP_INIT_DUMMY,
|
||||
JUMP_INIT(finish, _IO_str_finish),
|
||||
JUMP_INIT(overflow, _IO_str_chk_overflow),
|
||||
JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
|
||||
JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
|
||||
JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
|
||||
JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
|
||||
JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
|
||||
JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
|
||||
JUMP_INIT(seekpos, _IO_default_seekpos),
|
||||
JUMP_INIT(setbuf, _IO_default_setbuf),
|
||||
JUMP_INIT(sync, _IO_default_sync),
|
||||
JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
|
||||
JUMP_INIT(read, _IO_default_read),
|
||||
JUMP_INIT(write, _IO_default_write),
|
||||
JUMP_INIT(seek, _IO_default_seek),
|
||||
JUMP_INIT(close, _IO_default_close),
|
||||
JUMP_INIT(stat, _IO_default_stat),
|
||||
JUMP_INIT(showmanyc, _IO_default_showmanyc),
|
||||
JUMP_INIT(imbue, _IO_default_imbue)
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
__vsprintf_chk (char *s, int flags, size_t slen, const char *format,
|
||||
va_list args)
|
||||
{
|
||||
_IO_strfile f;
|
||||
int ret;
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
f._sbf._f._lock = NULL;
|
||||
#endif
|
||||
|
||||
if (slen == 0)
|
||||
__chk_fail ();
|
||||
|
||||
_IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
|
||||
_IO_JUMPS ((struct _IO_FILE_plus *) &f._sbf) = &_IO_str_chk_jumps;
|
||||
s[0] = '\0';
|
||||
_IO_str_init_static_internal (&f, s, slen - 1, s);
|
||||
|
||||
/* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
|
||||
can only come from read-only format strings. */
|
||||
if (flags > 0)
|
||||
f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY;
|
||||
|
||||
ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &f._sbf, format, args);
|
||||
|
||||
*f._sbf._f._IO_write_ptr = '\0';
|
||||
return ret;
|
||||
}
|
||||
libc_hidden_def (__vsprintf_chk)
|
||||
+32
-24
@@ -132,14 +132,14 @@ typedef struct __dirstream DIR;
|
||||
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern DIR *opendir (__const char *__name);
|
||||
extern DIR *opendir (__const char *__name) __nonnull ((1));
|
||||
|
||||
/* Close the directory stream DIRP.
|
||||
Return 0 if successful, -1 if not.
|
||||
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern int closedir (DIR *__dirp);
|
||||
extern int closedir (DIR *__dirp) __nonnull ((1));
|
||||
|
||||
/* Read a directory entry from DIRP. Return a pointer to a `struct
|
||||
dirent' describing the entry, or NULL for EOF or error. The
|
||||
@@ -152,17 +152,18 @@ extern int closedir (DIR *__dirp);
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
extern struct dirent *readdir (DIR *__dirp);
|
||||
extern struct dirent *readdir (DIR *__dirp) __nonnull ((1));
|
||||
#else
|
||||
# ifdef __REDIRECT
|
||||
extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64);
|
||||
extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64)
|
||||
__nonnull ((1));
|
||||
# else
|
||||
# define readdir readdir64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
extern struct dirent64 *readdir64 (DIR *__dirp);
|
||||
extern struct dirent64 *readdir64 (DIR *__dirp) __nonnull ((1));
|
||||
#endif
|
||||
|
||||
#if defined __USE_POSIX || defined __USE_MISC
|
||||
@@ -174,14 +175,15 @@ extern struct dirent64 *readdir64 (DIR *__dirp);
|
||||
# ifndef __USE_FILE_OFFSET64
|
||||
extern int readdir_r (DIR *__restrict __dirp,
|
||||
struct dirent *__restrict __entry,
|
||||
struct dirent **__restrict __result);
|
||||
struct dirent **__restrict __result)
|
||||
__nonnull ((1, 2, 3));
|
||||
# else
|
||||
# ifdef __REDIRECT
|
||||
extern int __REDIRECT (readdir_r,
|
||||
(DIR *__restrict __dirp,
|
||||
struct dirent *__restrict __entry,
|
||||
struct dirent **__restrict __result),
|
||||
readdir64_r);
|
||||
readdir64_r) __nonnull ((1, 2, 3));
|
||||
# else
|
||||
# define readdir_r readdir64_r
|
||||
# endif
|
||||
@@ -190,27 +192,28 @@ extern int __REDIRECT (readdir_r,
|
||||
# ifdef __USE_LARGEFILE64
|
||||
extern int readdir64_r (DIR *__restrict __dirp,
|
||||
struct dirent64 *__restrict __entry,
|
||||
struct dirent64 **__restrict __result);
|
||||
struct dirent64 **__restrict __result)
|
||||
__nonnull ((1, 2, 3));
|
||||
# endif
|
||||
#endif /* POSIX or misc */
|
||||
|
||||
/* Rewind DIRP to the beginning of the directory. */
|
||||
extern void rewinddir (DIR *__dirp) __THROW;
|
||||
extern void rewinddir (DIR *__dirp) __THROW __nonnull ((1));
|
||||
|
||||
#if defined __USE_BSD || defined __USE_MISC || defined __USE_XOPEN
|
||||
# include <bits/types.h>
|
||||
|
||||
/* Seek to position POS on DIRP. */
|
||||
extern void seekdir (DIR *__dirp, long int __pos) __THROW;
|
||||
extern void seekdir (DIR *__dirp, long int __pos) __THROW __nonnull ((1));
|
||||
|
||||
/* Return the current position of DIRP. */
|
||||
extern long int telldir (DIR *__dirp) __THROW;
|
||||
extern long int telldir (DIR *__dirp) __THROW __nonnull ((1));
|
||||
#endif
|
||||
|
||||
#if defined __USE_BSD || defined __USE_MISC
|
||||
|
||||
/* Return the file descriptor used by DIRP. */
|
||||
extern int dirfd (DIR *__dirp) __THROW;
|
||||
extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));
|
||||
|
||||
# if defined __OPTIMIZE__ && defined _DIR_dirfd
|
||||
# define dirfd(dirp) _DIR_dirfd (dirp)
|
||||
@@ -239,7 +242,8 @@ extern int dirfd (DIR *__dirp) __THROW;
|
||||
extern int scandir (__const char *__restrict __dir,
|
||||
struct dirent ***__restrict __namelist,
|
||||
int (*__selector) (__const struct dirent *),
|
||||
int (*__cmp) (__const void *, __const void *));
|
||||
int (*__cmp) (__const void *, __const void *))
|
||||
__nonnull ((1, 2));
|
||||
# else
|
||||
# ifdef __REDIRECT
|
||||
extern int __REDIRECT (scandir,
|
||||
@@ -247,7 +251,7 @@ extern int __REDIRECT (scandir,
|
||||
struct dirent ***__restrict __namelist,
|
||||
int (*__selector) (__const struct dirent *),
|
||||
int (*__cmp) (__const void *, __const void *)),
|
||||
scandir64);
|
||||
scandir64) __nonnull ((1, 2));
|
||||
# else
|
||||
# define scandir scandir64
|
||||
# endif
|
||||
@@ -259,18 +263,19 @@ extern int __REDIRECT (scandir,
|
||||
extern int scandir64 (__const char *__restrict __dir,
|
||||
struct dirent64 ***__restrict __namelist,
|
||||
int (*__selector) (__const struct dirent64 *),
|
||||
int (*__cmp) (__const void *, __const void *));
|
||||
int (*__cmp) (__const void *, __const void *))
|
||||
__nonnull ((1, 2));
|
||||
# endif
|
||||
|
||||
/* Function to compare two `struct dirent's alphabetically. */
|
||||
# ifndef __USE_FILE_OFFSET64
|
||||
extern int alphasort (__const void *__e1, __const void *__e2)
|
||||
__THROW __attribute_pure__;
|
||||
__THROW __attribute_pure__ __nonnull ((1, 2));
|
||||
# else
|
||||
# ifdef __REDIRECT
|
||||
extern int __REDIRECT_NTH (alphasort,
|
||||
(__const void *__e1, __const void *__e2),
|
||||
alphasort64) __attribute_pure__;
|
||||
alphasort64) __attribute_pure__ __nonnull ((1, 2));
|
||||
# else
|
||||
# define alphasort alphasort64
|
||||
# endif
|
||||
@@ -278,19 +283,20 @@ extern int __REDIRECT_NTH (alphasort,
|
||||
|
||||
# if defined __USE_GNU && defined __USE_LARGEFILE64
|
||||
extern int alphasort64 (__const void *__e1, __const void *__e2)
|
||||
__THROW __attribute_pure__;
|
||||
__THROW __attribute_pure__ __nonnull ((1, 2));
|
||||
# endif
|
||||
|
||||
# ifdef __USE_GNU
|
||||
/* Function to compare two `struct dirent's by name & version. */
|
||||
# ifndef __USE_FILE_OFFSET64
|
||||
extern int versionsort (__const void *__e1, __const void *__e2)
|
||||
__THROW __attribute_pure__;
|
||||
__THROW __attribute_pure__ __nonnull ((1, 2));
|
||||
# else
|
||||
# ifdef __REDIRECT
|
||||
extern int __REDIRECT_NTH (versionsort,
|
||||
(__const void *__e1, __const void *__e2),
|
||||
versionsort64) __attribute_pure__;
|
||||
versionsort64)
|
||||
__attribute_pure__ __nonnull ((1, 2));
|
||||
# else
|
||||
# define versionsort versionsort64
|
||||
# endif
|
||||
@@ -298,7 +304,7 @@ extern int __REDIRECT_NTH (versionsort,
|
||||
|
||||
# ifdef __USE_LARGEFILE64
|
||||
extern int versionsort64 (__const void *__e1, __const void *__e2)
|
||||
__THROW __attribute_pure__;
|
||||
__THROW __attribute_pure__ __nonnull ((1, 2));
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -309,14 +315,15 @@ extern int versionsort64 (__const void *__e1, __const void *__e2)
|
||||
# ifndef __USE_FILE_OFFSET64
|
||||
extern __ssize_t getdirentries (int __fd, char *__restrict __buf,
|
||||
size_t __nbytes,
|
||||
__off_t *__restrict __basep) __THROW;
|
||||
__off_t *__restrict __basep)
|
||||
__THROW __nonnull ((2, 4));
|
||||
# else
|
||||
# ifdef __REDIRECT
|
||||
extern __ssize_t __REDIRECT_NTH (getdirentries,
|
||||
(int __fd, char *__restrict __buf,
|
||||
size_t __nbytes,
|
||||
__off64_t *__restrict __basep),
|
||||
getdirentries64);
|
||||
getdirentries64) __nonnull ((2, 4));
|
||||
# else
|
||||
# define getdirentries getdirentries64
|
||||
# endif
|
||||
@@ -325,7 +332,8 @@ extern __ssize_t __REDIRECT_NTH (getdirentries,
|
||||
# ifdef __USE_LARGEFILE64
|
||||
extern __ssize_t getdirentries64 (int __fd, char *__restrict __buf,
|
||||
size_t __nbytes,
|
||||
__off64_t *__restrict __basep) __THROW;
|
||||
__off64_t *__restrict __basep)
|
||||
__THROW __nonnull ((2, 4));
|
||||
# endif
|
||||
|
||||
#endif /* Use BSD or misc. */
|
||||
|
||||
+15
-6
@@ -19,10 +19,13 @@
|
||||
subdir := dlfcn
|
||||
headers := bits/dlfcn.h dlfcn.h
|
||||
extra-libs := libdl
|
||||
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo
|
||||
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo \
|
||||
dlmopen
|
||||
routines := $(patsubst %,s%,$(libdl-routines))
|
||||
elide-routines.os := $(routines)
|
||||
distribute := dlopenold.c glreflib1.c glreflib2.c failtestmod.c \
|
||||
defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \
|
||||
modcxaatexit.c modstatic.c \
|
||||
modcxaatexit.c modstatic.c modstatic2.c \
|
||||
bug-dlsym1-lib1.c bug-dlsym1-lib2.c
|
||||
|
||||
extra-libs-others := libdl
|
||||
@@ -50,10 +53,11 @@ glreflib2.so-no-z-defs = yes
|
||||
errmsg1mod.so-no-z-defs = yes
|
||||
|
||||
ifeq (yesyesyes,$(build-static)$(build-shared)$(elf))
|
||||
tests += tststatic
|
||||
tests-static += tststatic
|
||||
modules-names += modstatic
|
||||
tests += tststatic tststatic2
|
||||
tests-static += tststatic tststatic2
|
||||
modules-names += modstatic modstatic2
|
||||
tststatic-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
|
||||
tststatic2-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
|
||||
endif
|
||||
|
||||
extra-objs += $(modules-names:=.os)
|
||||
@@ -105,7 +109,12 @@ $(objpfx)modatexit.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
|
||||
$(objpfx)tststatic: $(objpfx)libdl.a
|
||||
$(objpfx)tststatic.out: $(objpfx)tststatic $(objpfx)modstatic.so
|
||||
|
||||
$(objpfx)modstatic.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
|
||||
$(objpfx)tststatic2: $(objpfx)libdl.a
|
||||
$(objpfx)tststatic2.out: $(objpfx)tststatic2 $(objpfx)modstatic.so \
|
||||
$(objpfx)modstatic2.so
|
||||
|
||||
$(objpfx)modstatic2.so: $(libdl) $(common-objpfx)libc.so \
|
||||
$(common-objpfx)libc_nonshared.a
|
||||
|
||||
$(objpfx)bug-dlopen1: $(libdl)
|
||||
|
||||
|
||||
@@ -8,4 +8,10 @@ libdl {
|
||||
GLIBC_2.3.3 {
|
||||
dladdr1; dlinfo;
|
||||
}
|
||||
GLIBC_2.3.4 {
|
||||
dlmopen;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
_dlfcn_hook;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ int main(void)
|
||||
void *handle;
|
||||
char *c;
|
||||
|
||||
setenv ("LD_LIBRARY_PATH", "/home/roland/build/tls-libc/dlfcn", 1);
|
||||
|
||||
/* open lib1.so, which has the unresolved test symbol and a DT_NEEDED
|
||||
on lib2.so, which provides the symbol */
|
||||
if ((handle = dlopen("bug-dlsym1-lib1.so", RTLD_NOW)) == NULL) {
|
||||
|
||||
+20
-1
@@ -1,5 +1,6 @@
|
||||
/* Locate the shared object symbol nearest a given address.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2003, 2004
|
||||
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
|
||||
@@ -19,8 +20,26 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
int
|
||||
dladdr (const void *address, Dl_info *info)
|
||||
{
|
||||
return __dladdr (address, info);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
__dladdr (const void *address, Dl_info *info)
|
||||
{
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dladdr (address, info);
|
||||
# endif
|
||||
return _dl_addr (address, info, NULL, NULL);
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dladdr, dladdr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+20
-1
@@ -1,5 +1,5 @@
|
||||
/* Locate the shared object symbol nearest a given address.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004 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
|
||||
@@ -19,9 +19,24 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
int
|
||||
dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
|
||||
{
|
||||
return __dladdr1 (address, info, extra, flags);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
__dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
|
||||
{
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dladdr1 (address, info, extra, flags);
|
||||
# endif
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
default: /* Make this an error? */
|
||||
@@ -33,3 +48,7 @@ dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
|
||||
return _dl_addr (address, info, (struct link_map **) extra, NULL);
|
||||
}
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dladdr1, dladdr1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+22
-2
@@ -1,5 +1,6 @@
|
||||
/* Close a handle opened by `dlopen'.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2004
|
||||
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
|
||||
@@ -19,6 +20,16 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
int
|
||||
dlclose (void *handle)
|
||||
{
|
||||
return __dlclose (handle);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void
|
||||
dlclose_doit (void *handle)
|
||||
{
|
||||
@@ -26,7 +37,16 @@ dlclose_doit (void *handle)
|
||||
}
|
||||
|
||||
int
|
||||
dlclose (void *handle)
|
||||
__dlclose (void *handle)
|
||||
{
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlclose (handle);
|
||||
# endif
|
||||
|
||||
return _dlerror_run (dlclose_doit, handle) ? -1 : 0;
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dlclose, dlclose)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+51
-1
@@ -25,6 +25,16 @@
|
||||
#include <bits/libc-lock.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
char *
|
||||
dlerror (void)
|
||||
{
|
||||
return __dlerror ();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Type for storing results of dynamic loading actions. */
|
||||
struct dl_action_result
|
||||
{
|
||||
@@ -46,11 +56,16 @@ static void free_key_mem (void *mem);
|
||||
|
||||
|
||||
char *
|
||||
dlerror (void)
|
||||
__dlerror (void)
|
||||
{
|
||||
char *buf = NULL;
|
||||
struct dl_action_result *result;
|
||||
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlerror ();
|
||||
# endif
|
||||
|
||||
/* If we have not yet initialized the buffer do it now. */
|
||||
__libc_once (once, init);
|
||||
|
||||
@@ -99,6 +114,9 @@ dlerror (void)
|
||||
|
||||
return buf;
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dlerror, dlerror)
|
||||
# endif
|
||||
|
||||
int
|
||||
internal_function
|
||||
@@ -185,3 +203,35 @@ free_key_mem (void *mem)
|
||||
free (mem);
|
||||
__libc_setspecific (key, NULL);
|
||||
}
|
||||
|
||||
# ifdef SHARED
|
||||
|
||||
struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));
|
||||
libdl_hidden_data_def (_dlfcn_hook)
|
||||
|
||||
# else
|
||||
|
||||
static struct dlfcn_hook _dlfcn_hooks =
|
||||
{
|
||||
.dlopen = __dlopen,
|
||||
.dlclose = __dlclose,
|
||||
.dlsym = __dlsym,
|
||||
.dlvsym = __dlvsym,
|
||||
.dlerror = __dlerror,
|
||||
.dladdr = __dladdr,
|
||||
.dladdr1 = __dladdr1,
|
||||
.dlinfo = __dlinfo,
|
||||
.dlmopen = __dlmopen
|
||||
};
|
||||
|
||||
void
|
||||
__libc_register_dlfcn_hook (struct link_map *map)
|
||||
{
|
||||
struct dlfcn_hook **hook;
|
||||
|
||||
hook = (struct dlfcn_hook **) __libc_dlsym_private (map, "_dlfcn_hook");
|
||||
if (hook != NULL)
|
||||
*hook = &_dlfcn_hooks;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+24
-8
@@ -1,5 +1,5 @@
|
||||
/* User functions for run-time dynamic loading.
|
||||
Copyright (C) 1995-1999,2000,2001,2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999,2000,2001,2003,2004 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
|
||||
@@ -39,6 +39,14 @@
|
||||
the run-time address of the symbol called NAME in the global scope
|
||||
is returned. */
|
||||
# define RTLD_DEFAULT ((void *) 0)
|
||||
|
||||
|
||||
/* Type for namespace indeces. */
|
||||
typedef long int Lmid_t;
|
||||
|
||||
/* Special namespace ID values. */
|
||||
# define LM_ID_BASE 0 /* Initial namespace. */
|
||||
# define LM_ID_NEWLM -1 /* For dlmopen: request new namespace. */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,19 +58,23 @@ extern void *dlopen (__const char *__file, int __mode) __THROW;
|
||||
|
||||
/* Unmap and close a shared object opened by `dlopen'.
|
||||
The handle cannot be used again after calling `dlclose'. */
|
||||
extern int dlclose (void *__handle) __THROW;
|
||||
extern int dlclose (void *__handle) __THROW __nonnull ((1));
|
||||
|
||||
/* Find the run-time address in the shared object HANDLE refers to
|
||||
of the symbol called NAME. */
|
||||
extern void *dlsym (void *__restrict __handle,
|
||||
__const char *__restrict __name) __THROW;
|
||||
__const char *__restrict __name) __THROW __nonnull ((2));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Like `dlopen', but request object to be allocated in a new namespace. */
|
||||
extern void *dlmopen (Lmid_t __nsid, __const char *__file, int __mode) __THROW;
|
||||
|
||||
/* Find the run-time address in the shared object HANDLE refers to
|
||||
of the symbol called NAME with VERSION. */
|
||||
extern void *dlvsym (void *__restrict __handle,
|
||||
__const char *__restrict __name,
|
||||
__const char *__restrict __version) __THROW;
|
||||
__const char *__restrict __version)
|
||||
__THROW __nonnull ((2, 3));
|
||||
#endif
|
||||
|
||||
/* When any of the above functions fails, call this function
|
||||
@@ -84,11 +96,12 @@ typedef struct
|
||||
|
||||
/* Fill in *INFO with the following information about ADDRESS.
|
||||
Returns 0 iff no shared object's segments contain that address. */
|
||||
extern int dladdr (__const void *__address, Dl_info *__info) __THROW;
|
||||
extern int dladdr (__const void *__address, Dl_info *__info)
|
||||
__THROW __nonnull ((2));
|
||||
|
||||
/* Same as `dladdr', but additionally sets *EXTRA_INFO according to FLAGS. */
|
||||
extern int dladdr1 (__const void *__address, Dl_info *__info,
|
||||
void **__extra_info, int __flags) __THROW;
|
||||
void **__extra_info, int __flags) __THROW __nonnull ((2));
|
||||
|
||||
/* These are the possible values for the FLAGS argument to `dladdr1'.
|
||||
This indicates what extra information is stored at *EXTRA_INFO.
|
||||
@@ -109,11 +122,15 @@ enum
|
||||
On success, returns zero. On failure, returns -1 and records an error
|
||||
message to be fetched with `dlerror'. */
|
||||
extern int dlinfo (void *__restrict __handle,
|
||||
int __request, void *__restrict __arg);
|
||||
int __request, void *__restrict __arg)
|
||||
__THROW __nonnull ((1, 3));
|
||||
|
||||
/* These are the possible values for the REQUEST argument to `dlinfo'. */
|
||||
enum
|
||||
{
|
||||
/* Treat ARG as `lmid_t *'; store namespace ID for HANDLE there. */
|
||||
RTLD_DI_LMID = 1,
|
||||
|
||||
/* Treat ARG as `struct link_map **';
|
||||
store the `struct link_map *' for HANDLE there. */
|
||||
RTLD_DI_LINKMAP = 2,
|
||||
@@ -130,7 +147,6 @@ enum
|
||||
expand $ORIGIN in this shared object's dependency file names. */
|
||||
RTLD_DI_ORIGIN = 6,
|
||||
|
||||
RTLD_DI_LMID = 1, /* Unsupported, defined by Solaris. */
|
||||
RTLD_DI_CONFIGADDR = 3 /* Unsupported, defined by Solaris. */
|
||||
};
|
||||
|
||||
|
||||
+35
-10
@@ -22,6 +22,16 @@
|
||||
#include <ldsodefs.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
int
|
||||
dlinfo (void *handle, int request, void *arg)
|
||||
{
|
||||
return __dlinfo (handle, request, arg, RETURN_ADDRESS (0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct dlinfo_args
|
||||
{
|
||||
ElfW(Addr) caller;
|
||||
@@ -36,31 +46,36 @@ dlinfo_doit (void *argsblock)
|
||||
struct dlinfo_args *const args = argsblock;
|
||||
struct link_map *l = args->handle;
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
if (args->handle == RTLD_SELF)
|
||||
{
|
||||
Lmid_t nsid;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
break;
|
||||
for (nsid = 0; nsid < DL_NNS; ++nsid)
|
||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
break;
|
||||
|
||||
if (l == NULL)
|
||||
GLRO(dl_signal_error) (0, NULL, NULL, N_("\
|
||||
RTLD_SELF used in code not dynamically loaded"));
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
switch (args->request)
|
||||
{
|
||||
case RTLD_DI_LMID:
|
||||
case RTLD_DI_CONFIGADDR:
|
||||
default:
|
||||
GLRO(dl_signal_error) (0, NULL, NULL, N_("unsupported dlinfo request"));
|
||||
break;
|
||||
|
||||
case RTLD_DI_LMID:
|
||||
*(Lmid_t *) args->arg = l->l_ns;
|
||||
break;
|
||||
|
||||
case RTLD_DI_LINKMAP:
|
||||
*(struct link_map **) args->arg = l;
|
||||
break;
|
||||
@@ -79,9 +94,19 @@ RTLD_SELF used in code not dynamically loaded"));
|
||||
}
|
||||
|
||||
int
|
||||
dlinfo (void *handle, int request, void *arg)
|
||||
__dlinfo (void *handle, int request, void *arg DL_CALLER_DECL)
|
||||
{
|
||||
struct dlinfo_args args = { (ElfW(Addr)) RETURN_ADDRESS (0),
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlinfo (handle, request, arg,
|
||||
DL_CALLER);
|
||||
# endif
|
||||
|
||||
struct dlinfo_args args = { (ElfW(Addr)) DL_CALLER,
|
||||
handle, request, arg };
|
||||
return _dlerror_run (&dlinfo_doit, &args) ? -1 : 0;
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dlinfo, dlinfo)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2003,2004 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <stddef.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
void *
|
||||
dlmopen (Lmid_t nsid, const char *file, int mode)
|
||||
{
|
||||
return __dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
|
||||
}
|
||||
static_link_warning (dlmopen)
|
||||
|
||||
#else
|
||||
|
||||
struct dlmopen_args
|
||||
{
|
||||
/* Namespace ID. */
|
||||
Lmid_t nsid;
|
||||
/* The arguments for dlopen_doit. */
|
||||
const char *file;
|
||||
int mode;
|
||||
/* The return value of dlopen_doit. */
|
||||
void *new;
|
||||
/* Address of the caller. */
|
||||
const void *caller;
|
||||
};
|
||||
|
||||
static void
|
||||
dlmopen_doit (void *a)
|
||||
{
|
||||
struct dlmopen_args *args = (struct dlmopen_args *) a;
|
||||
|
||||
/* Non-shared code has no support for multiple namespaces. */
|
||||
if (args->nsid != LM_ID_BASE)
|
||||
# ifdef SHARED
|
||||
/* If trying to open the link map for the main executable the namespace
|
||||
must be the main one. */
|
||||
if (args->file == NULL)
|
||||
# endif
|
||||
GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
|
||||
args->caller, args->nsid);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
__dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL)
|
||||
{
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
|
||||
# endif
|
||||
|
||||
struct dlmopen_args args;
|
||||
args.nsid = nsid;
|
||||
args.file = file;
|
||||
args.mode = mode;
|
||||
args.caller = DL_CALLER;
|
||||
|
||||
# ifdef SHARED
|
||||
return _dlerror_run (dlmopen_doit, &args) ? NULL : args.new;
|
||||
# else
|
||||
if (_dlerror_run (dlmopen_doit, &args))
|
||||
return NULL;
|
||||
|
||||
__libc_register_dl_open_hook ((struct link_map *) args.new);
|
||||
__libc_register_dlfcn_hook ((struct link_map *) args.new);
|
||||
|
||||
return args.new;
|
||||
# endif
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dlmopen, dlmopen)
|
||||
# endif
|
||||
#endif
|
||||
+44
-7
@@ -1,5 +1,5 @@
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2003,2004 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
|
||||
@@ -20,6 +20,17 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
void *
|
||||
dlopen (const char *file, int mode)
|
||||
{
|
||||
return __dlopen (file, mode, RETURN_ADDRESS (0));
|
||||
}
|
||||
static_link_warning (dlopen)
|
||||
|
||||
#else
|
||||
|
||||
struct dlopen_args
|
||||
{
|
||||
/* The arguments for dlopen_doit. */
|
||||
@@ -31,27 +42,53 @@ struct dlopen_args
|
||||
const void *caller;
|
||||
};
|
||||
|
||||
|
||||
/* Non-shared code has no support for multiple namespaces. */
|
||||
# ifdef SHARED
|
||||
# define NS __LM_ID_CALLER
|
||||
# else
|
||||
# define NS LM_ID_BASE
|
||||
# endif
|
||||
|
||||
|
||||
static void
|
||||
dlopen_doit (void *a)
|
||||
{
|
||||
struct dlopen_args *args = (struct dlopen_args *) a;
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
|
||||
args->caller);
|
||||
args->caller, args->file == NULL ? LM_ID_BASE : NS);
|
||||
}
|
||||
|
||||
|
||||
extern void *__dlopen_check (const char *file, int mode);
|
||||
void *
|
||||
__dlopen_check (const char *file, int mode)
|
||||
__dlopen (const char *file, int mode DL_CALLER_DECL)
|
||||
{
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlopen (file, mode, DL_CALLER);
|
||||
# endif
|
||||
|
||||
struct dlopen_args args;
|
||||
args.file = file;
|
||||
args.mode = mode;
|
||||
args.caller = RETURN_ADDRESS (0);
|
||||
args.caller = DL_CALLER;
|
||||
|
||||
# ifdef SHARED
|
||||
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
|
||||
# else
|
||||
if (_dlerror_run (dlopen_doit, &args))
|
||||
return NULL;
|
||||
|
||||
__libc_register_dl_open_hook ((struct link_map *) args.new);
|
||||
__libc_register_dlfcn_hook ((struct link_map *) args.new);
|
||||
|
||||
return args.new;
|
||||
# endif
|
||||
}
|
||||
#include <shlib-compat.h>
|
||||
# ifdef SHARED
|
||||
# include <shlib-compat.h>
|
||||
strong_alias (__dlopen, __dlopen_check)
|
||||
versioned_symbol (libdl, __dlopen_check, dlopen, GLIBC_2_1);
|
||||
static_link_warning (dlopen)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+13
-2
@@ -1,5 +1,5 @@
|
||||
/* Load a shared object at run time.
|
||||
Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000, 2004 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
|
||||
@@ -37,13 +37,21 @@ struct dlopen_args
|
||||
};
|
||||
|
||||
|
||||
/* Non-shared code has no support for multiple namespaces. */
|
||||
#ifdef SHARED
|
||||
# define NS __LM_ID_CALLER
|
||||
#else
|
||||
# define NS LM_ID_BASE
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
dlopen_doit (void *a)
|
||||
{
|
||||
struct dlopen_args *args = (struct dlopen_args *) a;
|
||||
|
||||
args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
|
||||
args->caller);
|
||||
args->caller, args->file == NULL ? LM_ID_BASE : NS);
|
||||
}
|
||||
|
||||
extern void *__dlopen_nocheck (const char *file, int mode);
|
||||
@@ -59,6 +67,9 @@ __dlopen_nocheck (const char *file, int mode)
|
||||
mode |= RTLD_LAZY;
|
||||
args.mode = mode;
|
||||
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlopen (file, mode, RETURN_ADDRESS (0));
|
||||
|
||||
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
|
||||
}
|
||||
compat_symbol (libdl, __dlopen_nocheck, dlopen, GLIBC_2_0);
|
||||
|
||||
+21
-2
@@ -22,6 +22,16 @@
|
||||
|
||||
#include <ldsodefs.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
void *
|
||||
dlsym (void *handle, const char *name)
|
||||
{
|
||||
return __dlsym (handle, name, RETURN_ADDRESS (0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct dlsym_args
|
||||
{
|
||||
/* The arguments to dlsym_doit. */
|
||||
@@ -43,10 +53,15 @@ dlsym_doit (void *a)
|
||||
|
||||
|
||||
void *
|
||||
dlsym (void *handle, const char *name)
|
||||
__dlsym (void *handle, const char *name DL_CALLER_DECL)
|
||||
{
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlsym (handle, name, DL_CALLER);
|
||||
# endif
|
||||
|
||||
struct dlsym_args args;
|
||||
args.who = RETURN_ADDRESS (0);
|
||||
args.who = DL_CALLER;
|
||||
args.handle = handle;
|
||||
args.name = name;
|
||||
|
||||
@@ -59,3 +74,7 @@ dlsym (void *handle, const char *name)
|
||||
|
||||
return result;
|
||||
}
|
||||
# ifdef SHARED
|
||||
strong_alias (__dlsym, dlsym)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+22
-3
@@ -22,6 +22,17 @@
|
||||
|
||||
#include <ldsodefs.h>
|
||||
|
||||
#if !defined SHARED && defined IS_IN_libdl
|
||||
|
||||
void *
|
||||
weak_function
|
||||
dlvsym (void *handle, const char *name, const char *version_str)
|
||||
{
|
||||
return __dlvsym (handle, name, version_str, RETURN_ADDRESS (0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct dlvsym_args
|
||||
{
|
||||
/* The arguments to dlvsym_doit. */
|
||||
@@ -44,13 +55,18 @@ dlvsym_doit (void *a)
|
||||
}
|
||||
|
||||
void *
|
||||
__dlvsym (void *handle, const char *name, const char *version_str)
|
||||
__dlvsym (void *handle, const char *name, const char *version_str
|
||||
DL_CALLER_DECL)
|
||||
{
|
||||
struct dlvsym_args args;
|
||||
# ifdef SHARED
|
||||
if (__builtin_expect (_dlfcn_hook != NULL, 0))
|
||||
return _dlfcn_hook->dlvsym (handle, name, version_str, DL_CALLER);
|
||||
# endif
|
||||
|
||||
struct dlvsym_args args;
|
||||
args.handle = handle;
|
||||
args.name = name;
|
||||
args.who = RETURN_ADDRESS (0);
|
||||
args.who = DL_CALLER;
|
||||
args.version = version_str;
|
||||
|
||||
/* Protect against concurrent loads and unloads. */
|
||||
@@ -62,4 +78,7 @@ __dlvsym (void *handle, const char *name, const char *version_str)
|
||||
|
||||
return result;
|
||||
}
|
||||
# ifdef SHARED
|
||||
weak_alias (__dlvsym, dlvsym)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gnu/lib-names.h>
|
||||
|
||||
int test (FILE *out, int a);
|
||||
|
||||
int
|
||||
test (FILE *out, int a)
|
||||
{
|
||||
fputs ("in modstatic2.c (test)\n", out);
|
||||
|
||||
void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
fprintf (out, "nonexistent: %s\n", dlerror ());
|
||||
else
|
||||
exit (1);
|
||||
|
||||
handle = dlopen ("modstatic2.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
fprintf (out, "%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int (*test2) (FILE *, int);
|
||||
test2 = dlsym (handle, "test");
|
||||
if (test2 == NULL)
|
||||
{
|
||||
fprintf (out, "%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
if (test2 != test)
|
||||
{
|
||||
fprintf (out, "test %p != test2 %p\n", test, test2);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
Dl_info info;
|
||||
int res = dladdr (test2, &info);
|
||||
if (res == 0)
|
||||
{
|
||||
fputs ("dladdr returned 0\n", out);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr (info.dli_fname, "modstatic2.so") == NULL
|
||||
|| strcmp (info.dli_sname, "test") != 0)
|
||||
{
|
||||
fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
|
||||
exit (1);
|
||||
}
|
||||
if (info.dli_saddr != (void *) test2)
|
||||
{
|
||||
fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
ElfW(Sym) *sym;
|
||||
void *symp;
|
||||
res = dladdr1 (test2, &info, &symp, RTLD_DL_SYMENT);
|
||||
if (res == 0)
|
||||
{
|
||||
fputs ("dladdr1 returned 0\n", out);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr (info.dli_fname, "modstatic2.so") == NULL
|
||||
|| strcmp (info.dli_sname, "test") != 0)
|
||||
{
|
||||
fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
|
||||
exit (1);
|
||||
}
|
||||
if (info.dli_saddr != (void *) test2)
|
||||
{
|
||||
fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
|
||||
exit (1);
|
||||
}
|
||||
sym = symp;
|
||||
if (sym == NULL)
|
||||
{
|
||||
fputs ("sym == NULL\n", out);
|
||||
exit (1);
|
||||
}
|
||||
if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
|
||||
|| ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
|
||||
{
|
||||
fprintf (out, "bind %d visibility %d\n",
|
||||
(int) ELF32_ST_BIND (sym->st_info),
|
||||
(int) ELF32_ST_VISIBILITY (sym->st_other));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
Lmid_t lmid;
|
||||
res = dlinfo (handle, RTLD_DI_LMID, &lmid);
|
||||
if (res != 0)
|
||||
{
|
||||
fprintf (out, "dlinfo returned %d %s\n", res, dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
else if (lmid != LM_ID_BASE)
|
||||
{
|
||||
fprintf (out, "lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY);
|
||||
if (handle2 == NULL)
|
||||
{
|
||||
fprintf (out, "libdl.so: %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
#ifdef DO_VERSIONING
|
||||
if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL)
|
||||
{
|
||||
fprintf (out, "dlvsym: %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *(*dlsymfn) (void *, const char *);
|
||||
dlsymfn = dlsym (handle2, "dlsym");
|
||||
if (dlsymfn == NULL)
|
||||
{
|
||||
fprintf (out, "dlsym \"dlsym\": %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
void *test3 = dlsymfn (handle, "test");
|
||||
if (test3 == NULL)
|
||||
{
|
||||
fprintf (out, "%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
else if (test3 != (void *) test2)
|
||||
{
|
||||
fprintf (out, "test2 %p != test3 %p\n", test2, test3);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
dlclose (handle2);
|
||||
dlclose (handle);
|
||||
|
||||
handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
fprintf (out, "%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
dlclose (handle);
|
||||
|
||||
handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
fprintf (out, "LM_ID_NEWLM: %s\n", dlerror ());
|
||||
else
|
||||
{
|
||||
fputs ("LM_ID_NEWLM unexpectedly succeeded\n", out);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
handle = dlopen ("modstatic.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
fprintf (out, "%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int (*test4) (int);
|
||||
test4 = dlsym (handle, "test");
|
||||
if (test4 == NULL)
|
||||
{
|
||||
fprintf (out, "%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
res = test4 (16);
|
||||
if (res != 16 + 16)
|
||||
{
|
||||
fprintf (out, "modstatic.so (test) returned %d\n", res);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
res = dladdr1 (test4, &info, &symp, RTLD_DL_SYMENT);
|
||||
if (res == 0)
|
||||
{
|
||||
fputs ("dladdr1 returned 0\n", out);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr (info.dli_fname, "modstatic.so") == NULL
|
||||
|| strcmp (info.dli_sname, "test") != 0)
|
||||
{
|
||||
fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
|
||||
exit (1);
|
||||
}
|
||||
if (info.dli_saddr != (void *) test4)
|
||||
{
|
||||
fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test4);
|
||||
exit (1);
|
||||
}
|
||||
sym = symp;
|
||||
if (sym == NULL)
|
||||
{
|
||||
fputs ("sym == NULL\n", out);
|
||||
exit (1);
|
||||
}
|
||||
if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
|
||||
|| ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
|
||||
{
|
||||
fprintf (out, "bind %d visibility %d\n",
|
||||
(int) ELF32_ST_BIND (sym->st_info),
|
||||
(int) ELF32_ST_VISIBILITY (sym->st_other));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
dlclose (handle);
|
||||
|
||||
fputs ("leaving modstatic2.c (test)\n", out);
|
||||
return a + a;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include "dladdr.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dladdr1.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlclose.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlerror.c"
|
||||
@@ -1 +1 @@
|
||||
mvme136.ld
|
||||
#include "dlinfo.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlmopen.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlopen.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlsym.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlvsym.c"
|
||||
@@ -0,0 +1,166 @@
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gnu/lib-names.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
printf ("nonexistent: %s\n", dlerror ());
|
||||
else
|
||||
exit (1);
|
||||
|
||||
handle = dlopen ("modstatic2.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
printf ("%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int (*test) (FILE *, int);
|
||||
test = dlsym (handle, "test");
|
||||
if (test == NULL)
|
||||
{
|
||||
printf ("%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
Dl_info info;
|
||||
int res = dladdr (test, &info);
|
||||
if (res == 0)
|
||||
{
|
||||
puts ("dladdr returned 0");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr (info.dli_fname, "modstatic2.so") == NULL
|
||||
|| strcmp (info.dli_sname, "test") != 0)
|
||||
{
|
||||
printf ("fname %s sname %s\n", info.dli_fname, info.dli_sname);
|
||||
exit (1);
|
||||
}
|
||||
if (info.dli_saddr != (void *) test)
|
||||
{
|
||||
printf ("saddr %p != test %p\n", info.dli_saddr, test);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
ElfW(Sym) *sym;
|
||||
void *symp;
|
||||
res = dladdr1 (test, &info, &symp, RTLD_DL_SYMENT);
|
||||
if (res == 0)
|
||||
{
|
||||
puts ("dladdr1 returned 0");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr (info.dli_fname, "modstatic2.so") == NULL
|
||||
|| strcmp (info.dli_sname, "test") != 0)
|
||||
{
|
||||
printf ("fname %s sname %s\n", info.dli_fname, info.dli_sname);
|
||||
exit (1);
|
||||
}
|
||||
if (info.dli_saddr != (void *) test)
|
||||
{
|
||||
printf ("saddr %p != test %p\n", info.dli_saddr, test);
|
||||
exit (1);
|
||||
}
|
||||
sym = symp;
|
||||
if (sym == NULL)
|
||||
{
|
||||
puts ("sym == NULL\n");
|
||||
exit (1);
|
||||
}
|
||||
if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
|
||||
|| ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
|
||||
{
|
||||
printf ("bind %d visibility %d\n",
|
||||
(int) ELF32_ST_BIND (sym->st_info),
|
||||
(int) ELF32_ST_VISIBILITY (sym->st_other));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
Lmid_t lmid;
|
||||
res = dlinfo (handle, RTLD_DI_LMID, &lmid);
|
||||
if (res != 0)
|
||||
{
|
||||
printf ("dlinfo returned %d %s\n", res, dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
else if (lmid != LM_ID_BASE)
|
||||
{
|
||||
printf ("lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
res = test (stdout, 2);
|
||||
if (res != 4)
|
||||
{
|
||||
printf ("Got %i, expected 4\n", res);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY);
|
||||
if (handle2 == NULL)
|
||||
{
|
||||
printf ("libdl.so: %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
#ifdef DO_VERSIONING
|
||||
if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL)
|
||||
{
|
||||
printf ("dlvsym: %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *(*dlsymfn) (void *, const char *);
|
||||
dlsymfn = dlsym (handle2, "dlsym");
|
||||
if (dlsymfn == NULL)
|
||||
{
|
||||
printf ("dlsym \"dlsym\": %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
void *test2 = dlsymfn (handle, "test");
|
||||
if (test2 == NULL)
|
||||
{
|
||||
printf ("%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
else if (test2 != (void *) test)
|
||||
{
|
||||
printf ("test %p != test2 %p\n", test, test2);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
dlclose (handle2);
|
||||
dlclose (handle);
|
||||
|
||||
handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
printf ("%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
dlclose (handle);
|
||||
|
||||
handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
printf ("LM_ID_NEWLM: %s\n", dlerror ());
|
||||
else
|
||||
{
|
||||
puts ("LM_ID_NEWLM unexpectedly succeeded");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+22
-3
@@ -82,7 +82,8 @@ distribute := rtld-Rules \
|
||||
tst-array1.exp tst-array2.exp tst-array4.exp \
|
||||
tst-array2dep.c tst-piemod1.c \
|
||||
tst-execstack-mod.c tst-dlmodcount.c \
|
||||
check-textrel.c dl-sysdep.h test-dlopenrpathmod.c
|
||||
check-textrel.c dl-sysdep.h test-dlopenrpathmod.c \
|
||||
tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c
|
||||
|
||||
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
|
||||
@@ -152,7 +153,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
|
||||
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
|
||||
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
|
||||
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount tst-dlopenrpath
|
||||
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
|
||||
tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
tests-vis-yes = vismain
|
||||
@@ -185,7 +187,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
reldep8mod1 reldep8mod2 reldep8mod3 \
|
||||
reldep9mod1 reldep9mod2 reldep9mod3 \
|
||||
tst-alignmod $(modules-execstack-$(have-z-execstack)) \
|
||||
tst-dlopenrpathmod
|
||||
tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
|
||||
tst-dlmopen1mod
|
||||
ifeq (yes,$(have-initfini-array))
|
||||
modules-names += tst-array2dep
|
||||
endif
|
||||
@@ -754,3 +757,19 @@ $(objpfx)tst-dlopenrpath: $(objpfx)tst-dlopenrpathmod.so $(libdl)
|
||||
CFLAGS-tst-dlopenrpath.c += -DPFX=\"$(objpfx)\"
|
||||
LDFLAGS-tst-dlopenrpathmod.so += -Wl,-rpath,\$$ORIGIN/test-subdir
|
||||
$(objpfx)tst-dlopenrpath.out: $(objpfx)firstobj.so
|
||||
|
||||
$(objpfx)tst-deep1mod2.so: $(objpfx)tst-deep1mod3.so
|
||||
$(objpfx)tst-deep1: $(libdl) $(objpfx)tst-deep1mod1.so
|
||||
$(objpfx)tst-deep1.out: $(objpfx)tst-deep1mod2.so
|
||||
LDFLAGS-tst-deep1 += -rdynamic
|
||||
tst-deep1mod3.so-no-z-defs = yes
|
||||
|
||||
$(objpfx)tst-dlmopen1mod.so: $(libdl)
|
||||
$(objpfx)tst-dlmopen1: $(libdl)
|
||||
$(objpfx)tst-dlmopen1.out: $(objpfx)tst-dlmopen1mod.so
|
||||
|
||||
$(objpfx)tst-dlmopen2: $(libdl)
|
||||
$(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
|
||||
|
||||
$(objpfx)tst-dlmopen3: $(libdl)
|
||||
$(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
|
||||
|
||||
@@ -54,5 +54,7 @@ ld {
|
||||
_dl_get_tls_static_info; _dl_allocate_tls_init;
|
||||
_dl_tls_setup; _dl_rtld_di_serinfo;
|
||||
_dl_make_stack_executable;
|
||||
# Only here for gdb while a better method is developed.
|
||||
_dl_debug_state;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-23
@@ -28,7 +28,7 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
struct link_map **mapp, const ElfW(Sym) **symbolp)
|
||||
{
|
||||
const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
|
||||
struct link_map *l, *match;
|
||||
struct link_map *match;
|
||||
const ElfW(Sym) *symtab, *matchsym, *symtabend;
|
||||
const char *strtab;
|
||||
ElfW(Word) strtabsize;
|
||||
@@ -38,26 +38,27 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
|
||||
/* Find the highest-addressed object that ADDRESS is not below. */
|
||||
match = NULL;
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
if (addr >= l->l_map_start && addr < l->l_map_end)
|
||||
{
|
||||
/* We know ADDRESS lies within L if in any shared object.
|
||||
Make sure it isn't past the end of L's segments. */
|
||||
size_t n = l->l_phnum;
|
||||
if (n > 0)
|
||||
{
|
||||
do
|
||||
--n;
|
||||
while (l->l_phdr[n].p_type != PT_LOAD);
|
||||
if (addr >= (l->l_addr +
|
||||
l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
|
||||
/* Off the end of the highest-addressed shared object. */
|
||||
continue;
|
||||
}
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
|
||||
if (addr >= l->l_map_start && addr < l->l_map_end)
|
||||
{
|
||||
/* We know ADDRESS lies within L if in any shared object.
|
||||
Make sure it isn't past the end of L's segments. */
|
||||
size_t n = l->l_phnum;
|
||||
if (n > 0)
|
||||
{
|
||||
do
|
||||
--n;
|
||||
while (l->l_phdr[n].p_type != PT_LOAD);
|
||||
if (addr >= (l->l_addr +
|
||||
l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
|
||||
/* Off the end of the highest-addressed shared object. */
|
||||
continue;
|
||||
}
|
||||
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (match != NULL)
|
||||
@@ -67,8 +68,8 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
info->dli_fbase = (void *) match->l_map_start;
|
||||
|
||||
/* If this is the main program the information is incomplete. */
|
||||
if (__builtin_expect (l->l_name[0], 'a') == '\0'
|
||||
&& l->l_type == lt_executable)
|
||||
if (__builtin_expect (match->l_name[0], 'a') == '\0'
|
||||
&& match->l_type == lt_executable)
|
||||
info->dli_fname = _dl_argv[0];
|
||||
|
||||
symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]);
|
||||
@@ -91,6 +92,9 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
dynamic symbol table!! */
|
||||
for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab)
|
||||
if (addr >= match->l_addr + symtab->st_value
|
||||
#if defined USE_TLS
|
||||
&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
|
||||
#endif
|
||||
&& ((symtab->st_size == 0
|
||||
&& addr == match->l_addr + symtab->st_value)
|
||||
|| addr < match->l_addr + symtab->st_value + symtab->st_size)
|
||||
@@ -109,8 +113,10 @@ _dl_addr (const void *address, Dl_info *info,
|
||||
{
|
||||
/* We found a symbol close by. Fill in its name and exact
|
||||
address. */
|
||||
lookup_t matchl = LOOKUP_VALUE (match);
|
||||
|
||||
info->dli_sname = strtab + matchsym->st_name;
|
||||
info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
|
||||
info->dli_saddr = DL_SYMBOL_ADDRESS (matchl, matchsym);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+32
-30
@@ -35,44 +35,46 @@ _dl_check_caller (const void *caller, enum allowmask mask)
|
||||
#endif
|
||||
static const char expected4[] = LD_SO;
|
||||
|
||||
for (struct link_map *l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
if (caller >= (const void *) l->l_map_start
|
||||
&& caller < (const void *) l->l_text_end)
|
||||
{
|
||||
/* The address falls into this DSO's address range. Check the
|
||||
name. */
|
||||
if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
|
||||
return 0;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
|
||||
l = l->l_next)
|
||||
if (caller >= (const void *) l->l_map_start
|
||||
&& caller < (const void *) l->l_text_end)
|
||||
{
|
||||
/* The address falls into this DSO's address range. Check the
|
||||
name. */
|
||||
if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
|
||||
return 0;
|
||||
#ifdef LIBPTHREAD_SO
|
||||
if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
|
||||
return 0;
|
||||
|
||||
struct libname_list *runp = l->l_libname;
|
||||
struct libname_list *runp = l->l_libname;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
|
||||
return 0;
|
||||
while (runp != NULL)
|
||||
{
|
||||
if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
|
||||
return 0;
|
||||
#ifdef LIBPTHREAD_SO
|
||||
if ((mask & allow_libpthread)
|
||||
&& strcmp (expected3, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_libpthread)
|
||||
&& strcmp (expected3, runp->name) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
|
||||
return 0;
|
||||
if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
|
||||
return 0;
|
||||
|
||||
runp = runp->next;
|
||||
}
|
||||
runp = runp->next;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Maybe the dynamic linker is not yet on the list. */
|
||||
if ((mask & allow_ldso) != 0
|
||||
|
||||
+98
-43
@@ -130,6 +130,10 @@ _dl_close (void *_map)
|
||||
/* Acquire the lock. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
/* One less direct use. */
|
||||
assert (map->l_direct_opencount > 0);
|
||||
--map->l_direct_opencount;
|
||||
|
||||
/* Decrement the reference count. */
|
||||
if (map->l_opencount > 1 || map->l_type != lt_loaded)
|
||||
{
|
||||
@@ -141,6 +145,12 @@ _dl_close (void *_map)
|
||||
/* Decrement the object's reference counter, not the dependencies'. */
|
||||
--map->l_opencount;
|
||||
|
||||
/* If the direct use counter reaches zero we have to decrement
|
||||
all the dependencies' usage counter. */
|
||||
if (map->l_direct_opencount == 0)
|
||||
for (i = 1; i < map->l_searchlist.r_nlist; ++i)
|
||||
--map->l_searchlist.r_list[i]->l_opencount;
|
||||
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
return;
|
||||
}
|
||||
@@ -167,12 +177,13 @@ _dl_close (void *_map)
|
||||
for (i = 1; list[i] != NULL; ++i)
|
||||
if ((list[i]->l_flags_1 & DF_1_NODELETE) == 0
|
||||
/* Decrement counter. */
|
||||
&& --new_opencount[i] == 0)
|
||||
&& (assert (new_opencount[i] > 0), --new_opencount[i] == 0))
|
||||
{
|
||||
void mark_removed (struct link_map *remmap)
|
||||
{
|
||||
/* Test whether this object was also loaded directly. */
|
||||
if (remmap->l_searchlist.r_list != NULL)
|
||||
if (remmap->l_searchlist.r_list != NULL
|
||||
&& remmap->l_direct_opencount > 0)
|
||||
{
|
||||
/* In this case we have to decrement all the dependencies of
|
||||
this object. They are all in MAP's dependency list. */
|
||||
@@ -184,6 +195,7 @@ _dl_close (void *_map)
|
||||
|| ! dep_list[j]->l_init_called)
|
||||
{
|
||||
assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
|
||||
assert (new_opencount[dep_list[j]->l_idx] > 0);
|
||||
if (--new_opencount[dep_list[j]->l_idx] == 0)
|
||||
{
|
||||
assert (dep_list[j]->l_type == lt_loaded);
|
||||
@@ -197,17 +209,53 @@ _dl_close (void *_map)
|
||||
unsigned int j;
|
||||
for (j = 0; j < remmap->l_reldepsact; ++j)
|
||||
{
|
||||
struct link_map *depmap = remmap->l_reldeps[j];
|
||||
|
||||
/* Find out whether this object is in our list. */
|
||||
if (remmap->l_reldeps[j]->l_idx < nopencount
|
||||
&& (list[remmap->l_reldeps[j]->l_idx]
|
||||
== remmap->l_reldeps[j]))
|
||||
/* Yes, it is. */
|
||||
if (--new_opencount[remmap->l_reldeps[j]->l_idx] == 0)
|
||||
{
|
||||
/* This one is now gone, too. */
|
||||
assert (remmap->l_reldeps[j]->l_type == lt_loaded);
|
||||
mark_removed (remmap->l_reldeps[j]);
|
||||
}
|
||||
if (depmap->l_idx < nopencount
|
||||
&& list[depmap->l_idx] == depmap)
|
||||
{
|
||||
/* Yes, it is. If is has a search list, make a
|
||||
recursive call to handle this. */
|
||||
if (depmap->l_searchlist.r_list != NULL)
|
||||
{
|
||||
assert (new_opencount[depmap->l_idx] > 0);
|
||||
if (--new_opencount[depmap->l_idx] == 0)
|
||||
{
|
||||
/* This one is now gone, too. */
|
||||
assert (depmap->l_type == lt_loaded);
|
||||
mark_removed (depmap);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we have to handle the dependency
|
||||
deallocation here. */
|
||||
unsigned int k;
|
||||
for (k = 0; depmap->l_initfini[k] != NULL; ++k)
|
||||
{
|
||||
struct link_map *rl = depmap->l_initfini[k];
|
||||
|
||||
if (rl->l_idx < nopencount
|
||||
&& list[rl->l_idx] == rl)
|
||||
{
|
||||
assert (new_opencount[rl->l_idx] > 0);
|
||||
if (--new_opencount[rl->l_idx] == 0)
|
||||
{
|
||||
/* Another module to remove. */
|
||||
assert (rl->l_type == lt_loaded);
|
||||
mark_removed (rl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (rl->l_opencount > 0);
|
||||
if (--rl->l_opencount == 0)
|
||||
mark_removed (rl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,7 +273,8 @@ _dl_close (void *_map)
|
||||
{
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
|
||||
GLRO(dl_debug_printf) ("\ncalling fini: %s\n\n", imap->l_name);
|
||||
GLRO(dl_debug_printf) ("\ncalling fini: %s [%lu]\n\n",
|
||||
imap->l_name, imap->l_ns);
|
||||
|
||||
/* Call its termination function. Do not do it for
|
||||
half-cooked objects. */
|
||||
@@ -340,18 +389,21 @@ _dl_close (void *_map)
|
||||
if (__builtin_expect (imap->l_global, 0))
|
||||
{
|
||||
/* This object is in the global scope list. Remove it. */
|
||||
unsigned int cnt = GL(dl_main_searchlist)->r_nlist;
|
||||
unsigned int cnt
|
||||
= GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
|
||||
|
||||
do
|
||||
--cnt;
|
||||
while (GL(dl_main_searchlist)->r_list[cnt] != imap);
|
||||
while (GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt]
|
||||
!= imap);
|
||||
|
||||
/* The object was already correctly registered. */
|
||||
while (++cnt < GL(dl_main_searchlist)->r_nlist)
|
||||
GL(dl_main_searchlist)->r_list[cnt - 1]
|
||||
= GL(dl_main_searchlist)->r_list[cnt];
|
||||
while (++cnt
|
||||
< GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist)
|
||||
GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt - 1]
|
||||
= GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt];
|
||||
|
||||
--GL(dl_main_searchlist)->r_nlist;
|
||||
--GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
@@ -442,19 +494,18 @@ _dl_close (void *_map)
|
||||
DL_UNMAP (imap);
|
||||
|
||||
/* Finally, unlink the data structure and free it. */
|
||||
#ifdef SHARED
|
||||
/* We will unlink the first object only if this is a statically
|
||||
linked program. */
|
||||
assert (imap->l_prev != NULL);
|
||||
imap->l_prev->l_next = imap->l_next;
|
||||
#else
|
||||
if (imap->l_prev != NULL)
|
||||
imap->l_prev->l_next = imap->l_next;
|
||||
else
|
||||
GL(dl_loaded) = imap->l_next;
|
||||
{
|
||||
#ifdef SHARED
|
||||
assert (imap->l_ns != LM_ID_BASE);
|
||||
#endif
|
||||
--GL(dl_nloaded);
|
||||
if (imap->l_next)
|
||||
GL(dl_ns)[imap->l_ns]._ns_loaded = imap->l_next;
|
||||
}
|
||||
|
||||
--GL(dl_ns)[imap->l_ns]._ns_nloaded;
|
||||
if (imap->l_next != NULL)
|
||||
imap->l_next->l_prev = imap->l_prev;
|
||||
|
||||
free (imap->l_versions);
|
||||
@@ -528,7 +579,7 @@ _dl_close (void *_map)
|
||||
if (any_tls)
|
||||
{
|
||||
if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
|
||||
__libc_fatal (_("TLS generation counter wrapped! Please send report with the 'glibcbug' script."));
|
||||
__libc_fatal (_("TLS generation counter wrapped! Please report as described in <http://www.gnu.org/software/libc/bugs.html>."));
|
||||
|
||||
if (tls_free_end == GL(dl_tls_static_used))
|
||||
GL(dl_tls_static_used) = tls_free_start;
|
||||
@@ -596,22 +647,26 @@ free_slotinfo (struct dtv_slotinfo_list **elemp)
|
||||
|
||||
libc_freeres_fn (free_mem)
|
||||
{
|
||||
if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0
|
||||
&& (GL(dl_main_searchlist)->r_nlist
|
||||
== GLRO(dl_initial_searchlist).r_nlist))
|
||||
{
|
||||
/* All object dynamically loaded by the program are unloaded. Free
|
||||
the memory allocated for the global scope variable. */
|
||||
struct link_map **old = GL(dl_main_searchlist)->r_list;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
|
||||
&& (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
|
||||
// XXX Check whether we need NS-specific initial_searchlist
|
||||
== GLRO(dl_initial_searchlist).r_nlist))
|
||||
{
|
||||
/* All object dynamically loaded by the program are unloaded. Free
|
||||
the memory allocated for the global scope variable. */
|
||||
struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
|
||||
|
||||
/* Put the old map in. */
|
||||
GL(dl_main_searchlist)->r_list = GLRO(dl_initial_searchlist).r_list;
|
||||
/* Signal that the original map is used. */
|
||||
GL(dl_global_scope_alloc) = 0;
|
||||
/* Put the old map in. */
|
||||
GL(dl_ns)[ns]._ns_main_searchlist->r_list
|
||||
// XXX Check whether we need NS-specific initial_searchlist
|
||||
= GLRO(dl_initial_searchlist).r_list;
|
||||
/* Signal that the original map is used. */
|
||||
GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
|
||||
|
||||
/* Now free the old map. */
|
||||
free (old);
|
||||
}
|
||||
/* Now free the old map. */
|
||||
free (old);
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
|
||||
|
||||
+3
-1
@@ -54,8 +54,10 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
|
||||
(map) = resolve_conflict_map; \
|
||||
} while (0)
|
||||
|
||||
/* Prelinking makes no sense for anything but the main namespace. */
|
||||
assert (l->l_ns == LM_ID_BASE);
|
||||
struct link_map *resolve_conflict_map __attribute__ ((__unused__))
|
||||
= GL(dl_loaded);
|
||||
= GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
#include "dynamic-link.h"
|
||||
|
||||
|
||||
+4
-1
@@ -39,7 +39,9 @@ _dl_debug_initialize (ElfW(Addr) ldbase)
|
||||
/* Tell the debugger where to find the map of loaded objects. */
|
||||
_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
_r_debug.r_ldbase = ldbase;
|
||||
_r_debug.r_map = GL(dl_loaded);
|
||||
// XXX This is problematic. It means we cannot tell the debugger
|
||||
// XXX about namespaces other than the main one.
|
||||
_r_debug.r_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
_r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state;
|
||||
}
|
||||
|
||||
@@ -55,3 +57,4 @@ void
|
||||
_dl_debug_state (void)
|
||||
{
|
||||
}
|
||||
rtld_hidden_def (_dl_debug_state)
|
||||
|
||||
+4
-3
@@ -63,7 +63,8 @@ openaux (void *a)
|
||||
args->aux = _dl_map_object (args->map, args->name, 0,
|
||||
(args->map->l_type == lt_executable
|
||||
? lt_library : args->map->l_type),
|
||||
args->trace_mode, args->open_mode);
|
||||
args->trace_mode, args->open_mode,
|
||||
args->map->l_ns);
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
@@ -509,8 +510,8 @@ _dl_map_object_deps (struct link_map *map,
|
||||
runp->map->l_reserved = 0;
|
||||
}
|
||||
|
||||
if (__builtin_expect(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
|
||||
&& map == GL(dl_loaded))
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
|
||||
&& map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
|
||||
{
|
||||
/* If we are to compute conflicts, we have to build local scope
|
||||
for each library, not just the ultimate loader. */
|
||||
|
||||
+155
-121
@@ -32,153 +32,187 @@ internal_function
|
||||
_dl_fini (void)
|
||||
{
|
||||
/* Lots of fun ahead. We have to call the destructors for all still
|
||||
loaded objects. The problem is that the ELF specification now
|
||||
demands that dependencies between the modules are taken into account.
|
||||
I.e., the destructor for a module is called before the ones for any
|
||||
of its dependencies.
|
||||
loaded objects, in all namespaces. The problem is that the ELF
|
||||
specification now demands that dependencies between the modules
|
||||
are taken into account. I.e., the destructor for a module is
|
||||
called before the ones for any of its dependencies.
|
||||
|
||||
To make things more complicated, we cannot simply use the reverse
|
||||
order of the constructors. Since the user might have loaded objects
|
||||
using `dlopen' there are possibly several other modules with its
|
||||
dependencies to be taken into account. Therefore we have to start
|
||||
determining the order of the modules once again from the beginning. */
|
||||
unsigned int i;
|
||||
unsigned int nloaded;
|
||||
struct link_map *l;
|
||||
struct link_map **maps;
|
||||
struct link_map **maps = NULL;
|
||||
size_t maps_size = 0;
|
||||
|
||||
/* Protect against concurrent loads and unloads. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
nloaded = GL(dl_nloaded);
|
||||
|
||||
/* XXX Could it be (in static binaries) that there is no object loaded? */
|
||||
assert (nloaded > 0);
|
||||
|
||||
/* Now we can allocate an array to hold all the pointers and copy
|
||||
the pointers in. */
|
||||
maps = (struct link_map **) alloca (nloaded * sizeof (struct link_map *));
|
||||
for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next)
|
||||
/* We run the destructors of the main namespaces last. As for the
|
||||
other namespaces, we pick run the destructors in them in reverse
|
||||
order of the namespace ID. */
|
||||
for (Lmid_t cnt = DL_NNS - 1; cnt >= 0; --cnt)
|
||||
{
|
||||
assert (i < nloaded);
|
||||
/* Protect against concurrent loads and unloads. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
maps[i++] = l;
|
||||
unsigned int nloaded = GL(dl_ns)[cnt]._ns_nloaded;
|
||||
|
||||
/* Bump l_opencount of all objects so that they are not dlclose()ed
|
||||
from underneath us. */
|
||||
++l->l_opencount;
|
||||
}
|
||||
assert (i == nloaded);
|
||||
/* XXX Could it be (in static binaries) that there is no object
|
||||
loaded? */
|
||||
assert (cnt != LM_ID_BASE || nloaded > 0);
|
||||
|
||||
/* Now we have to do the sorting. */
|
||||
for (l = GL(dl_loaded)->l_next; l != NULL; l = l->l_next)
|
||||
{
|
||||
unsigned int j;
|
||||
unsigned int k;
|
||||
|
||||
/* Find the place in the 'maps' array. */
|
||||
for (j = 1; maps[j] != l; ++j)
|
||||
;
|
||||
|
||||
/* Find all object for which the current one is a dependency and
|
||||
move the found object (if necessary) in front. */
|
||||
for (k = j + 1; k < nloaded; ++k)
|
||||
/* Now we can allocate an array to hold all the pointers and copy
|
||||
the pointers in. */
|
||||
if (maps_size < nloaded * sizeof (struct link_map *))
|
||||
{
|
||||
struct link_map **runp = maps[k]->l_initfini;
|
||||
if (runp != NULL)
|
||||
if (maps_size == 0)
|
||||
{
|
||||
while (*runp != NULL)
|
||||
if (*runp == l)
|
||||
maps_size = nloaded * sizeof (struct link_map *);
|
||||
maps = (struct link_map **) alloca (maps_size);
|
||||
}
|
||||
else
|
||||
maps = (struct link_map **)
|
||||
extend_alloca (maps, maps_size,
|
||||
nloaded * sizeof (struct link_map *));
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
struct link_map *l;
|
||||
for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
|
||||
/* Do not handle ld.so in secondary namespaces. */
|
||||
if (l == l->l_real)
|
||||
{
|
||||
assert (i < nloaded);
|
||||
|
||||
maps[i++] = l;
|
||||
|
||||
/* Bump l_opencount of all objects so that they are not
|
||||
dlclose()ed from underneath us. */
|
||||
++l->l_opencount;
|
||||
}
|
||||
assert (cnt != LM_ID_BASE || i == nloaded);
|
||||
assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
|
||||
unsigned int nmaps = i;
|
||||
|
||||
if (nmaps != 0)
|
||||
{
|
||||
/* Now we have to do the sorting. */
|
||||
l = GL(dl_ns)[cnt]._ns_loaded;
|
||||
if (cnt == LM_ID_BASE)
|
||||
/* The main executable always comes first. */
|
||||
l = l->l_next;
|
||||
for (; l != NULL; l = l->l_next)
|
||||
/* Do not handle ld.so in secondary namespaces. */
|
||||
if (l == l->l_real)
|
||||
{
|
||||
/* Find the place in the 'maps' array. */
|
||||
unsigned int j;
|
||||
for (j = cnt == LM_ID_BASE ? 1 : 0; maps[j] != l; ++j)
|
||||
assert (j < nmaps);
|
||||
|
||||
/* Find all object for which the current one is a dependency
|
||||
and move the found object (if necessary) in front. */
|
||||
for (unsigned int k = j + 1; k < nmaps; ++k)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
struct link_map **runp = maps[k]->l_initfini;
|
||||
if (runp != NULL)
|
||||
{
|
||||
while (*runp != NULL)
|
||||
if (*runp == l)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j++] = here;
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j++] = here;
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else
|
||||
++runp;
|
||||
}
|
||||
|
||||
if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
|
||||
{
|
||||
unsigned int m = maps[k]->l_reldepsact;
|
||||
struct link_map **relmaps = maps[k]->l_reldeps;
|
||||
|
||||
while (m-- > 0)
|
||||
{
|
||||
if (relmaps[m] == l)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j] = here;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
++runp;
|
||||
}
|
||||
|
||||
if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
|
||||
{
|
||||
unsigned int m = maps[k]->l_reldepsact;
|
||||
struct link_map **relmaps = maps[k]->l_reldeps;
|
||||
|
||||
while (m-- > 0)
|
||||
{
|
||||
if (relmaps[m] == l)
|
||||
{
|
||||
struct link_map *here = maps[k];
|
||||
|
||||
/* Move it now. */
|
||||
memmove (&maps[j] + 1,
|
||||
&maps[j],
|
||||
(k - j) * sizeof (struct link_map *));
|
||||
maps[j] = here;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We do not rely on the linked list of loaded object anymore from
|
||||
this point on. We have our own list here (maps). The various
|
||||
members of this list cannot vanish since the open count is too
|
||||
high and will be decremented in this loop. So we release the
|
||||
lock so that some code which might be called from a destructor
|
||||
can directly or indirectly access the lock. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
/* We do not rely on the linked list of loaded object anymore from
|
||||
this point on. We have our own list here (maps). The various
|
||||
members of this list cannot vanish since the open count is too
|
||||
high and will be decremented in this loop. So we release the
|
||||
lock so that some code which might be called from a destructor
|
||||
can directly or indirectly access the lock. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
|
||||
/* 'maps' now contains the objects in the right order. Now call the
|
||||
destructors. We have to process this array from the front. */
|
||||
for (i = 0; i < nloaded; ++i)
|
||||
{
|
||||
l = maps[i];
|
||||
|
||||
if (l->l_init_called)
|
||||
/* 'maps' now contains the objects in the right order. Now call the
|
||||
destructors. We have to process this array from the front. */
|
||||
for (i = 0; i < nmaps; ++i)
|
||||
{
|
||||
/* Make sure nothing happens if we are called twice. */
|
||||
l->l_init_called = 0;
|
||||
l = maps[i];
|
||||
|
||||
/* Don't call the destructors for objects we are not supposed to. */
|
||||
if (l->l_name[0] == '\0' && l->l_type == lt_executable)
|
||||
continue;
|
||||
|
||||
/* Is there a destructor function? */
|
||||
if (l->l_info[DT_FINI_ARRAY] == NULL && l->l_info[DT_FINI] == NULL)
|
||||
continue;
|
||||
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
|
||||
_dl_debug_printf ("\ncalling fini: %s\n\n",
|
||||
l->l_name[0] ? l->l_name : rtld_progname);
|
||||
|
||||
/* First see whether an array is given. */
|
||||
if (l->l_info[DT_FINI_ARRAY] != NULL)
|
||||
if (l->l_init_called)
|
||||
{
|
||||
ElfW(Addr) *array =
|
||||
(ElfW(Addr) *) (l->l_addr
|
||||
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||
unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||
/ sizeof (ElfW(Addr)));
|
||||
while (i-- > 0)
|
||||
((fini_t) array[i]) ();
|
||||
/* Make sure nothing happens if we are called twice. */
|
||||
l->l_init_called = 0;
|
||||
|
||||
/* Don't call the destructors for objects we are not
|
||||
supposed to. */
|
||||
if (l->l_name[0] == '\0' && l->l_type == lt_executable)
|
||||
continue;
|
||||
|
||||
/* Is there a destructor function? */
|
||||
if (l->l_info[DT_FINI_ARRAY] == NULL
|
||||
&& l->l_info[DT_FINI] == NULL)
|
||||
continue;
|
||||
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
|
||||
0))
|
||||
_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
|
||||
l->l_name[0] ? l->l_name : rtld_progname,
|
||||
cnt);
|
||||
|
||||
/* First see whether an array is given. */
|
||||
if (l->l_info[DT_FINI_ARRAY] != NULL)
|
||||
{
|
||||
ElfW(Addr) *array =
|
||||
(ElfW(Addr) *) (l->l_addr
|
||||
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||
unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||
/ sizeof (ElfW(Addr)));
|
||||
while (i-- > 0)
|
||||
((fini_t) array[i]) ();
|
||||
}
|
||||
|
||||
/* Next try the old-style destructor. */
|
||||
if (l->l_info[DT_FINI] != NULL)
|
||||
((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
|
||||
}
|
||||
|
||||
/* Next try the old-style destructor. */
|
||||
if (l->l_info[DT_FINI] != NULL)
|
||||
((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
|
||||
/* Correct the previous increment. */
|
||||
--l->l_opencount;
|
||||
}
|
||||
|
||||
/* Correct the previous increment. */
|
||||
--l->l_opencount;
|
||||
}
|
||||
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
|
||||
|
||||
+21
-3
@@ -42,14 +42,32 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
__libc_cleanup_push (cancel_handler, 0);
|
||||
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
/* We have to determine the namespace of the caller since this determines
|
||||
which namespace is reported. */
|
||||
const void *caller = RETURN_ADDRESS (0);
|
||||
size_t nloaded = GL(dl_ns)[0]._ns_nloaded;
|
||||
Lmid_t ns = 0;
|
||||
for (Lmid_t cnt = DL_NNS - 1; cnt > 0; --cnt)
|
||||
for (struct link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
|
||||
{
|
||||
/* We have to count the total number of loaded objects. */
|
||||
nloaded += GL(dl_ns)[cnt]._ns_nloaded;
|
||||
|
||||
if (caller >= (const void *) l->l_map_start
|
||||
&& caller < (const void *) l->l_map_end)
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
ns = cnt;
|
||||
}
|
||||
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
info.dlpi_addr = l->l_addr;
|
||||
info.dlpi_name = l->l_name;
|
||||
info.dlpi_phdr = l->l_phdr;
|
||||
info.dlpi_phnum = l->l_phnum;
|
||||
info.dlpi_adds = GL(dl_load_adds);
|
||||
info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
|
||||
info.dlpi_subs = GL(dl_load_adds) - nloaded;
|
||||
ret = callback (&info, sizeof (struct dl_phdr_info), data);
|
||||
if (ret)
|
||||
break;
|
||||
@@ -87,7 +105,7 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
|
||||
info.dlpi_phdr = _dl_phdr;
|
||||
info.dlpi_phnum = _dl_phnum;
|
||||
info.dlpi_adds = GL(dl_load_adds);
|
||||
info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
|
||||
info.dlpi_subs = GL(dl_load_adds) - GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
|
||||
ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+39
-26
@@ -77,7 +77,7 @@ 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, args->mode, NULL);
|
||||
args->map = _dl_open (args->name, args->mode, NULL, __LM_ID_CALLER);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -121,7 +121,6 @@ do_dlsym_private (void *ptr)
|
||||
vers.hidden = 1;
|
||||
/* vers.hash = _dl_elf_hash (version); */
|
||||
vers.hash = 0x0963cf85;
|
||||
/* FIXME: Shouldn't we use libc.so.6* here? */
|
||||
vers.filename = NULL;
|
||||
|
||||
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
||||
@@ -156,24 +155,37 @@ __libc_dlopen_mode (const char *name, int mode)
|
||||
if (dlerror_run (do_dlopen, &args))
|
||||
return NULL;
|
||||
|
||||
struct do_dlsym_args sargs;
|
||||
sargs.map = args.map;
|
||||
sargs.name = "_dl_open_hook";
|
||||
|
||||
if (! dlerror_run (do_dlsym_private, &sargs))
|
||||
{
|
||||
struct dl_open_hook **hook
|
||||
= (struct dl_open_hook **)
|
||||
(DL_SYMBOL_ADDRESS (sargs.loadbase, sargs.ref));
|
||||
if (hook != NULL)
|
||||
*hook = &_dl_open_hook;
|
||||
}
|
||||
|
||||
__libc_register_dl_open_hook (args.map);
|
||||
__libc_register_dlfcn_hook (args.map);
|
||||
return (void *) args.map;
|
||||
#endif
|
||||
}
|
||||
libc_hidden_def (__libc_dlopen_mode)
|
||||
|
||||
#ifndef SHARED
|
||||
void *
|
||||
__libc_dlsym_private (struct link_map *map, const char *name)
|
||||
{
|
||||
struct do_dlsym_args sargs;
|
||||
sargs.map = map;
|
||||
sargs.name = name;
|
||||
|
||||
if (! dlerror_run (do_dlsym_private, &sargs))
|
||||
return DL_SYMBOL_ADDRESS (sargs.loadbase, sargs.ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
__libc_register_dl_open_hook (struct link_map *map)
|
||||
{
|
||||
struct dl_open_hook **hook;
|
||||
|
||||
hook = (struct dl_open_hook **) __libc_dlsym_private (map, "_dl_open_hook");
|
||||
if (hook != NULL)
|
||||
*hook = &_dl_open_hook;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *
|
||||
__libc_dlsym (void *map, const char *name)
|
||||
{
|
||||
@@ -217,18 +229,19 @@ libc_freeres_fn (free_mem)
|
||||
}
|
||||
|
||||
/* Remove all additional names added to the objects. */
|
||||
for (l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
{
|
||||
struct libname_list *lnp = l->l_libname->next;
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
struct libname_list *lnp = l->l_libname->next;
|
||||
|
||||
l->l_libname->next = NULL;
|
||||
l->l_libname->next = NULL;
|
||||
|
||||
while (lnp != NULL)
|
||||
{
|
||||
struct libname_list *old = lnp;
|
||||
lnp = lnp->next;
|
||||
if (! old->dont_free)
|
||||
while (lnp != NULL)
|
||||
{
|
||||
struct libname_list *old = lnp;
|
||||
lnp = lnp->next;
|
||||
if (! old->dont_free)
|
||||
free (old);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+71
-35
@@ -699,7 +699,7 @@ _dl_init_paths (const char *llp)
|
||||
|
||||
#ifdef SHARED
|
||||
/* This points to the map of the main object. */
|
||||
l = GL(dl_loaded);
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l != NULL)
|
||||
{
|
||||
assert (l->l_type != lt_loaded);
|
||||
@@ -795,10 +795,10 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
|
||||
if (l->l_prev == NULL)
|
||||
/* No other module loaded. This happens only in the static library,
|
||||
or in rtld under --verify. */
|
||||
GL(dl_loaded) = NULL;
|
||||
GL(dl_ns)[l->l_ns]._ns_loaded = NULL;
|
||||
else
|
||||
l->l_prev->l_next = NULL;
|
||||
--GL(dl_nloaded);
|
||||
--GL(dl_ns)[l->l_ns]._ns_nloaded;
|
||||
free (l);
|
||||
}
|
||||
free (realname);
|
||||
@@ -815,7 +815,7 @@ static
|
||||
struct link_map *
|
||||
_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
char *realname, struct link_map *loader, int l_type,
|
||||
int mode, void **stack_endp)
|
||||
int mode, void **stack_endp, Lmid_t nsid)
|
||||
{
|
||||
struct link_map *l = NULL;
|
||||
const ElfW(Ehdr) *header;
|
||||
@@ -839,7 +839,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
}
|
||||
|
||||
/* Look again to see if the real name matched another already loaded. */
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
|
||||
if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
|
||||
{
|
||||
/* The object is already loaded.
|
||||
@@ -854,6 +854,31 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
return l;
|
||||
}
|
||||
|
||||
#ifdef SHARED
|
||||
/* When loading into a namespace other than the base one we must
|
||||
avoid loading ld.so since there can only be one copy. Ever. */
|
||||
if (__builtin_expect (nsid != LM_ID_BASE, 0)
|
||||
&& ((st.st_ino == GL(dl_rtld_map).l_ino
|
||||
&& st.st_dev == GL(dl_rtld_map).l_dev)
|
||||
|| _dl_name_match_p (name, &GL(dl_rtld_map))))
|
||||
{
|
||||
/* This is indeed ld.so. Create a new link_map which refers to
|
||||
the real one for almost everything. */
|
||||
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||
if (l == NULL)
|
||||
goto fail_new;
|
||||
|
||||
/* Refer to the real descriptor. */
|
||||
l->l_real = &GL(dl_rtld_map);
|
||||
|
||||
/* No need to bump the refcount of the real object, ld.so will
|
||||
never be unloaded. */
|
||||
__close (fd);
|
||||
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mode & RTLD_NOLOAD)
|
||||
/* We are not supposed to load the object unless it is already
|
||||
loaded. So return now. */
|
||||
@@ -861,7 +886,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
|
||||
/* Print debugging message. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
_dl_debug_printf ("file=%s; generating link map\n", name);
|
||||
_dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid);
|
||||
|
||||
/* This is the ELF header. We read it in `open_verify'. */
|
||||
header = (void *) fbp->buf;
|
||||
@@ -881,9 +906,12 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
#endif
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
l = _dl_new_object (realname, name, l_type, loader);
|
||||
if (__builtin_expect (! l, 0))
|
||||
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||
if (__builtin_expect (l == NULL, 0))
|
||||
{
|
||||
#ifdef SHARED
|
||||
fail_new:
|
||||
#endif
|
||||
errstring = N_("cannot create shared object descriptor");
|
||||
goto call_lose_errno;
|
||||
}
|
||||
@@ -959,12 +987,12 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
}
|
||||
|
||||
c = &loadcmds[nloadcmds++];
|
||||
c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
|
||||
c->mapstart = ph->p_vaddr & ~(GLRO(dl_pagesize) - 1);
|
||||
c->mapend = ((ph->p_vaddr + ph->p_filesz + GLRO(dl_pagesize) - 1)
|
||||
& ~(GLRO(dl_pagesize) - 1));
|
||||
c->dataend = ph->p_vaddr + ph->p_filesz;
|
||||
c->allocend = ph->p_vaddr + ph->p_memsz;
|
||||
c->mapoff = ph->p_offset & ~(ph->p_align - 1);
|
||||
c->mapoff = ph->p_offset & ~(GLRO(dl_pagesize) - 1);
|
||||
|
||||
/* Determine whether there is a gap between the last segment
|
||||
and this one. */
|
||||
@@ -1355,15 +1383,12 @@ cannot enable executable stack as shared object requires");
|
||||
|
||||
/* If this object has DT_SYMBOLIC set modify now its scope. We don't
|
||||
have to do this for the main map. */
|
||||
if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
|
||||
if ((mode & RTLD_DEEPBIND) == 0
|
||||
&& __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
|
||||
&& &l->l_searchlist != l->l_scope[0])
|
||||
{
|
||||
/* Create an appropriate searchlist. It contains only this map.
|
||||
|
||||
XXX This is the definition of DT_SYMBOLIC in SysVr4. The old
|
||||
GNU ld.so implementation had a different interpretation which
|
||||
is more reasonable. We are prepared to add this possibility
|
||||
back as part of a GNU extension of the ELF format. */
|
||||
This is the definition of DT_SYMBOLIC in SysVr4. */
|
||||
l->l_symbolic_searchlist.r_list =
|
||||
(struct link_map **) malloc (sizeof (struct link_map *));
|
||||
|
||||
@@ -1774,7 +1799,7 @@ open_path (const char *name, size_t namelen, int preloaded,
|
||||
struct link_map *
|
||||
internal_function
|
||||
_dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
int type, int trace_mode, int mode)
|
||||
int type, int trace_mode, int mode, Lmid_t nsid)
|
||||
{
|
||||
int fd;
|
||||
char *realname;
|
||||
@@ -1782,8 +1807,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
struct link_map *l;
|
||||
struct filebuf fb;
|
||||
|
||||
assert (nsid >= 0);
|
||||
assert (nsid < DL_NNS);
|
||||
|
||||
/* Look for this name among those already loaded. */
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
|
||||
{
|
||||
/* If the requested name matches the soname of a loaded object,
|
||||
use that object. Elide this check for names that have not
|
||||
@@ -1815,9 +1843,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
/* Display information if we are debugging. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
|
||||
&& loader != NULL)
|
||||
_dl_debug_printf ("\nfile=%s; needed by %s\n", name,
|
||||
_dl_debug_printf ("\nfile=%s [%lu]; needed by %s [%lu]\n", name, nsid,
|
||||
loader->l_name[0]
|
||||
? loader->l_name : rtld_progname);
|
||||
? loader->l_name : rtld_progname, loader->l_ns);
|
||||
|
||||
if (strchr (name, '/') == NULL)
|
||||
{
|
||||
@@ -1826,7 +1854,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
size_t namelen = strlen (name) + 1;
|
||||
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
|
||||
_dl_debug_printf ("find library=%s; searching\n", name);
|
||||
_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
|
||||
|
||||
fd = -1;
|
||||
|
||||
@@ -1842,12 +1870,15 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
&realname, &fb);
|
||||
|
||||
/* If dynamically linked, try the DT_RPATH of the executable
|
||||
itself. */
|
||||
l = GL(dl_loaded);
|
||||
if (fd == -1 && l && l->l_type != lt_loaded && l != loader
|
||||
&& l->l_rpath_dirs.dirs != (void *) -1)
|
||||
fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
|
||||
&realname, &fb);
|
||||
itself. NB: we do this for lookups in any namespace. */
|
||||
if (fd == -1)
|
||||
{
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l && l->l_type != lt_loaded && l != loader
|
||||
&& cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
|
||||
fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
|
||||
&realname, &fb);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||
@@ -1873,7 +1904,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
if (cached != NULL)
|
||||
{
|
||||
#ifdef SHARED
|
||||
l = loader ?: GL(dl_loaded);
|
||||
// XXX Correct to unconditionally default to namespace 0?
|
||||
l = loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
#else
|
||||
l = loader;
|
||||
#endif
|
||||
@@ -1923,7 +1955,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
/* Finally, try the default path. */
|
||||
if (fd == -1
|
||||
&& ((l = loader ?: GL(dl_loaded)) == NULL
|
||||
&& ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
|
||||
|| __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
|
||||
&& rtld_search_dirs.dirs != (void *) -1)
|
||||
fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
|
||||
@@ -1968,7 +2000,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
if ((name_copy = local_strdup (name)) == NULL
|
||||
|| (l = _dl_new_object (name_copy, name, type, loader)) == NULL)
|
||||
|| (l = _dl_new_object (name_copy, name, type, loader,
|
||||
mode, nsid)) == NULL)
|
||||
_dl_signal_error (ENOMEM, name, NULL,
|
||||
N_("cannot create shared object descriptor"));
|
||||
/* Signal that this is a faked entry. */
|
||||
@@ -1989,7 +2022,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
void *stack_end = __libc_stack_end;
|
||||
return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode,
|
||||
&stack_end);
|
||||
&stack_end, nsid);
|
||||
}
|
||||
|
||||
|
||||
@@ -2049,10 +2082,13 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
|
||||
while (l != NULL);
|
||||
|
||||
/* If dynamically linked, try the DT_RPATH of the executable itself. */
|
||||
l = GL(dl_loaded);
|
||||
if (l != NULL && l->l_type != lt_loaded && l != loader)
|
||||
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
|
||||
add_path (&l->l_rpath_dirs, XXX_RPATH);
|
||||
if (loader->l_ns == LM_ID_BASE)
|
||||
{
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l != NULL && l->l_type != lt_loaded && l != loader)
|
||||
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
|
||||
add_path (&l->l_rpath_dirs, XXX_RPATH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||
|
||||
+12
-7
@@ -137,7 +137,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
|
||||
reference is still available. There is a brief period in
|
||||
which the object could have been removed since we found the
|
||||
definition. */
|
||||
runp = GL(dl_loaded);
|
||||
runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
|
||||
while (runp != NULL && runp != map)
|
||||
runp = runp->l_next;
|
||||
|
||||
@@ -182,13 +182,18 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
|
||||
for (list = map->l_initfini; *list != NULL; ++list)
|
||||
++(*list)->l_opencount;
|
||||
|
||||
/* As if it is opened through _dl_open. */
|
||||
++map->l_direct_opencount;
|
||||
|
||||
/* Display information if we are debugging. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
_dl_debug_printf ("\
|
||||
\nfile=%s; needed by %s (relocation dependency)\n\n",
|
||||
\nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
|
||||
map->l_name[0] ? map->l_name : rtld_progname,
|
||||
map->l_ns,
|
||||
undef_map->l_name[0]
|
||||
? undef_map->l_name : rtld_progname);
|
||||
? undef_map->l_name : rtld_progname,
|
||||
undef_map->l_ns);
|
||||
}
|
||||
else
|
||||
/* Whoa, that was bad luck. We have to search again. */
|
||||
@@ -408,8 +413,8 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||
struct sym_val val = { NULL, NULL };
|
||||
|
||||
if ((GLRO(dl_trace_prelink_map) == NULL
|
||||
|| GLRO(dl_trace_prelink_map) == GL(dl_loaded))
|
||||
&& undef_map != GL(dl_loaded))
|
||||
|| GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
|
||||
&& undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
|
||||
{
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
|
||||
@@ -421,12 +426,12 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||
conflict = 1;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
# ifdef USE_TLS
|
||||
if (value->s
|
||||
&& (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
|
||||
== STT_TLS, 0)))
|
||||
type_class = 4;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
if (conflict
|
||||
|| GLRO(dl_trace_prelink_map) == undef_map
|
||||
|
||||
@@ -354,6 +354,13 @@ __strsep (char **stringp, const char *delim)
|
||||
weak_alias (__strsep, strsep)
|
||||
strong_alias (__strsep, __strsep_g)
|
||||
|
||||
void
|
||||
__attribute__ ((noreturn))
|
||||
__chk_fail (void)
|
||||
{
|
||||
_exit (127);
|
||||
}
|
||||
rtld_hidden_def (__chk_fail)
|
||||
|
||||
/* The '_itoa_lower_digits' variable in libc.so is able to handle bases
|
||||
up to 36. We don't need this here. */
|
||||
|
||||
+17
-7
@@ -32,7 +32,7 @@
|
||||
struct link_map *
|
||||
internal_function
|
||||
_dl_new_object (char *realname, const char *libname, int type,
|
||||
struct link_map *loader)
|
||||
struct link_map *loader, int mode, Lmid_t nsid)
|
||||
{
|
||||
struct link_map *l;
|
||||
int idx;
|
||||
@@ -45,6 +45,7 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
new->l_real = new;
|
||||
new->l_libname = newname = (struct libname_list *) (new + 1);
|
||||
newname->name = (char *) memcpy (newname + 1, libname, libname_len);
|
||||
/* newname->next = NULL; We use calloc therefore not necessary. */
|
||||
@@ -56,6 +57,7 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
#if defined USE_TLS && NO_TLS_OFFSET != 0
|
||||
new->l_tls_offset = NO_TLS_OFFSET;
|
||||
#endif
|
||||
new->l_ns = nsid;
|
||||
|
||||
/* new->l_global = 0; We use calloc therefore not necessary. */
|
||||
|
||||
@@ -68,9 +70,9 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
/* Counter for the scopes we have to handle. */
|
||||
idx = 0;
|
||||
|
||||
if (GL(dl_loaded) != NULL)
|
||||
if (GL(dl_ns)[nsid]._ns_loaded != NULL)
|
||||
{
|
||||
l = GL(dl_loaded);
|
||||
l = GL(dl_ns)[nsid]._ns_loaded;
|
||||
while (l->l_next != NULL)
|
||||
l = l->l_next;
|
||||
new->l_prev = l;
|
||||
@@ -78,11 +80,11 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
l->l_next = new;
|
||||
|
||||
/* Add the global scope. */
|
||||
new->l_scope[idx++] = &GL(dl_loaded)->l_searchlist;
|
||||
new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
|
||||
}
|
||||
else
|
||||
GL(dl_loaded) = new;
|
||||
++GL(dl_nloaded);
|
||||
GL(dl_ns)[nsid]._ns_loaded = new;
|
||||
++GL(dl_ns)[nsid]._ns_nloaded;
|
||||
++GL(dl_load_adds);
|
||||
|
||||
/* If we have no loader the new object acts as it. */
|
||||
@@ -95,7 +97,15 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
|
||||
/* Insert the scope if it isn't the global scope we already added. */
|
||||
if (idx == 0 || &loader->l_searchlist != new->l_scope[0])
|
||||
new->l_scope[idx] = &loader->l_searchlist;
|
||||
{
|
||||
if ((mode & RTLD_DEEPBIND) != 0 && idx != 0)
|
||||
{
|
||||
new->l_scope[1] = new->l_scope[0];
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
new->l_scope[idx] = &loader->l_searchlist;
|
||||
}
|
||||
|
||||
new->l_local_scope[0] = &new->l_searchlist;
|
||||
|
||||
|
||||
+101
-47
@@ -72,6 +72,8 @@ struct dl_open_args
|
||||
/* This is the caller if _dl_open(). */
|
||||
const void *caller_dl_open;
|
||||
struct link_map *map;
|
||||
/* Namespace ID. */
|
||||
Lmid_t nsid;
|
||||
};
|
||||
|
||||
|
||||
@@ -101,15 +103,17 @@ add_to_global (struct link_map *new)
|
||||
in an realloc() call. Therefore we allocate a completely new
|
||||
array the first time we have to add something to the locale scope. */
|
||||
|
||||
if (GL(dl_global_scope_alloc) == 0)
|
||||
if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0)
|
||||
{
|
||||
/* This is the first dynamic object given global scope. */
|
||||
GL(dl_global_scope_alloc) = GL(dl_main_searchlist)->r_nlist + to_add + 8;
|
||||
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
|
||||
= GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8;
|
||||
new_global = (struct link_map **)
|
||||
malloc (GL(dl_global_scope_alloc) * sizeof (struct link_map *));
|
||||
malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
|
||||
* sizeof (struct link_map *));
|
||||
if (new_global == NULL)
|
||||
{
|
||||
GL(dl_global_scope_alloc) = 0;
|
||||
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0;
|
||||
nomem:
|
||||
GLRO(dl_signal_error) (ENOMEM, new->l_libname->name, NULL,
|
||||
N_("cannot extend global scope"));
|
||||
@@ -117,25 +121,26 @@ add_to_global (struct link_map *new)
|
||||
}
|
||||
|
||||
/* Copy over the old entries. */
|
||||
memcpy (new_global, GL(dl_main_searchlist)->r_list,
|
||||
(GL(dl_main_searchlist)->r_nlist * sizeof (struct link_map *)));
|
||||
|
||||
GL(dl_main_searchlist)->r_list = new_global;
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list
|
||||
= memcpy (new_global,
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
|
||||
(GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist
|
||||
* sizeof (struct link_map *)));
|
||||
}
|
||||
else if (GL(dl_main_searchlist)->r_nlist + to_add
|
||||
> GL(dl_global_scope_alloc))
|
||||
else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add
|
||||
> GL(dl_ns)[new->l_ns]._ns_global_scope_alloc)
|
||||
{
|
||||
/* We have to extend the existing array of link maps in the
|
||||
main map. */
|
||||
new_global = (struct link_map **)
|
||||
realloc (GL(dl_main_searchlist)->r_list,
|
||||
((GL(dl_global_scope_alloc) + to_add + 8)
|
||||
realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
|
||||
((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8)
|
||||
* sizeof (struct link_map *)));
|
||||
if (new_global == NULL)
|
||||
goto nomem;
|
||||
|
||||
GL(dl_global_scope_alloc) += to_add + 8;
|
||||
GL(dl_main_searchlist)->r_list = new_global;
|
||||
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8;
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global;
|
||||
}
|
||||
|
||||
/* Now add the new entries. */
|
||||
@@ -146,9 +151,9 @@ add_to_global (struct link_map *new)
|
||||
if (map->l_global == 0)
|
||||
{
|
||||
map->l_global = 1;
|
||||
GL(dl_main_searchlist)->r_list[GL(dl_main_searchlist)->r_nlist]
|
||||
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist]
|
||||
= map;
|
||||
++GL(dl_main_searchlist)->r_nlist;
|
||||
++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,28 +180,42 @@ dl_open_worker (void *a)
|
||||
GLRO(dl_signal_error) (0, "dlopen", NULL, N_("invalid caller"));
|
||||
|
||||
/* Determine the caller's map if necessary. This is needed in case
|
||||
we have a DST or when the file name has no path in which case we
|
||||
need to look along the RUNPATH/RPATH of the caller. */
|
||||
we have a DST, when we don't know the namespace ID we have to put
|
||||
the new object in, or when the file name has no path in which
|
||||
case we need to look along the RUNPATH/RPATH of the caller. */
|
||||
const char *dst = strchr (file, '$');
|
||||
if (dst != NULL || strchr (file, '/') == NULL)
|
||||
if (dst != NULL || args->nsid == __LM_ID_CALLER
|
||||
|| strchr (file, '/') == NULL)
|
||||
{
|
||||
const void *caller_dlopen = args->caller_dlopen;
|
||||
|
||||
/* We have to find out from which object the caller is calling. */
|
||||
call_map = NULL;
|
||||
for (l = GL(dl_loaded); l; l = l->l_next)
|
||||
if (caller_dlopen >= (const void *) l->l_map_start
|
||||
&& caller_dlopen < (const void *) l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
call_map = l;
|
||||
break;
|
||||
}
|
||||
/* We have to find out from which object the caller is calling.
|
||||
By default we assume this is the main application. */
|
||||
call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
if (call_map == NULL)
|
||||
/* In this case we assume this is the main application. */
|
||||
call_map = GL(dl_loaded);
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||
if (caller_dlopen >= (const void *) l->l_map_start
|
||||
&& caller_dlopen < (const void *) l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
assert (ns == l->l_ns);
|
||||
call_map = l;
|
||||
goto found_caller;
|
||||
}
|
||||
|
||||
found_caller:
|
||||
if (args->nsid == __LM_ID_CALLER)
|
||||
{
|
||||
#ifndef SHARED
|
||||
/* In statically linked apps there might be no loaded object. */
|
||||
if (call_map == NULL)
|
||||
args->nsid = LM_ID_BASE;
|
||||
else
|
||||
#endif
|
||||
args->nsid = call_map->l_ns;
|
||||
}
|
||||
}
|
||||
|
||||
/* Maybe we have to expand a DST. */
|
||||
@@ -238,7 +257,7 @@ dl_open_worker (void *a)
|
||||
|
||||
/* Load the named object. */
|
||||
args->map = new = GLRO(dl_map_object) (call_map, file, 0, lt_loaded, 0,
|
||||
mode | __RTLD_CALLMAP);
|
||||
mode | __RTLD_CALLMAP, args->nsid);
|
||||
|
||||
/* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
|
||||
set and the object is not already loaded. */
|
||||
@@ -252,32 +271,43 @@ dl_open_worker (void *a)
|
||||
/* This happens only if we load a DSO for 'sprof'. */
|
||||
return;
|
||||
|
||||
/* This object is directly loaded. */
|
||||
++new->l_direct_opencount;
|
||||
|
||||
/* It was already open. */
|
||||
if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
|
||||
{
|
||||
/* Let the user know about the opencount. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
GLRO(dl_debug_printf) ("opening file=%s; opencount == %u\n\n",
|
||||
new->l_name, new->l_opencount);
|
||||
GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
|
||||
new->l_name, new->l_ns, new->l_opencount);
|
||||
|
||||
/* If the user requested the object to be in the global namespace
|
||||
but it is not so far, add it now. */
|
||||
if ((mode & RTLD_GLOBAL) && new->l_global == 0)
|
||||
(void) add_to_global (new);
|
||||
|
||||
/* Increment just the reference counter of the object. */
|
||||
++new->l_opencount;
|
||||
if (new->l_direct_opencount == 1)
|
||||
/* This is the only direct reference. Increment all the
|
||||
dependencies' reference counter. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
++new->l_searchlist.r_list[i]->l_opencount;
|
||||
else
|
||||
/* Increment just the reference counter of the object. */
|
||||
++new->l_opencount;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
GLRO(dl_map_object_deps) (new, NULL, 0, 0, mode & __RTLD_DLOPEN);
|
||||
GLRO(dl_map_object_deps) (new, NULL, 0, 0,
|
||||
mode & (__RTLD_DLOPEN | RTLD_DEEPBIND));
|
||||
|
||||
/* So far, so good. Now check the versions. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
if (new->l_searchlist.r_list[i]->l_versions == NULL)
|
||||
(void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i], 0, 0);
|
||||
if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
|
||||
(void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i]->l_real,
|
||||
0, 0);
|
||||
|
||||
#ifdef SCOPE_DEBUG
|
||||
show_scope (new);
|
||||
@@ -294,7 +324,7 @@ dl_open_worker (void *a)
|
||||
l = l->l_next;
|
||||
while (1)
|
||||
{
|
||||
if (! l->l_relocated)
|
||||
if (! l->l_real->l_relocated)
|
||||
{
|
||||
#ifdef SHARED
|
||||
if (GLRO(dl_profile) != NULL)
|
||||
@@ -348,7 +378,7 @@ dl_open_worker (void *a)
|
||||
loaded object to the scope. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
if (++new->l_searchlist.r_list[i]->l_opencount > 1
|
||||
&& new->l_searchlist.r_list[i]->l_type == lt_loaded)
|
||||
&& new->l_real->l_searchlist.r_list[i]->l_type == lt_loaded)
|
||||
{
|
||||
struct link_map *imap = new->l_searchlist.r_list[i];
|
||||
struct r_scope_elem **runp = imap->l_scope;
|
||||
@@ -476,7 +506,7 @@ cannot create TLS data structures"));
|
||||
/* Bump the generation number if necessary. */
|
||||
if (any_tls)
|
||||
if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
|
||||
__libc_fatal (_("TLS generation counter wrapped! Please send report with the 'glibcbug' script."));
|
||||
__libc_fatal (_("TLS generation counter wrapped! Please report this."));
|
||||
#endif
|
||||
|
||||
/* Run the initializer functions of new objects. */
|
||||
@@ -502,14 +532,14 @@ cannot create TLS data structures"));
|
||||
|
||||
/* Let the user know about the opencount. */
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
|
||||
GLRO(dl_debug_printf) ("opening file=%s; opencount == %u\n\n",
|
||||
new->l_name, new->l_opencount);
|
||||
GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
|
||||
new->l_name, new->l_ns, new->l_opencount);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
internal_function
|
||||
_dl_open (const char *file, int mode, const void *caller_dlopen)
|
||||
_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
|
||||
{
|
||||
struct dl_open_args args;
|
||||
const char *objname;
|
||||
@@ -524,11 +554,35 @@ _dl_open (const char *file, int mode, const void *caller_dlopen)
|
||||
/* Make sure we are alone. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
if (nsid == LM_ID_NEWLM)
|
||||
{
|
||||
/* Find a new namespace. */
|
||||
for (nsid = 1; nsid < DL_NNS; ++nsid)
|
||||
if (GL(dl_ns)[nsid]._ns_loaded == NULL)
|
||||
break;
|
||||
|
||||
if (nsid == DL_NNS)
|
||||
{
|
||||
/* No more namespace available. */
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
|
||||
GLRO(dl_signal_error) (EINVAL, file, NULL, N_("\
|
||||
no more namespaces available for dlmopen()"));
|
||||
}
|
||||
}
|
||||
/* Never allow loading a DSO in a namespace which is empty. Such
|
||||
direct placements is only causing problems. */
|
||||
else if (nsid != LM_ID_BASE && nsid != __LM_ID_CALLER
|
||||
&& GL(dl_ns)[nsid]._ns_nloaded == 0)
|
||||
GLRO(dl_signal_error) (EINVAL, file, NULL,
|
||||
N_("invalid target namespace in dlmopen()"));
|
||||
|
||||
args.file = file;
|
||||
args.mode = mode;
|
||||
args.caller_dlopen = caller_dlopen;
|
||||
args.caller_dl_open = RETURN_ADDRESS (0);
|
||||
args.map = NULL;
|
||||
args.nsid = nsid;
|
||||
errcode = GLRO(dl_catch_error) (&objname, &errstring, dl_open_worker, &args);
|
||||
|
||||
#ifndef MAP_COPY
|
||||
|
||||
+24
-25
@@ -67,10 +67,8 @@ const char *_dl_origin_path;
|
||||
/* Nonzero if runtime lookup should not update the .got/.plt. */
|
||||
int _dl_bind_not;
|
||||
|
||||
/* Initially empty list of loaded objects. */
|
||||
struct link_map *_dl_loaded;
|
||||
/* Number of object in the _dl_loaded list. */
|
||||
unsigned int _dl_nloaded;
|
||||
/* Namespace information. */
|
||||
struct link_namespaces _dl_ns[DL_NNS];
|
||||
|
||||
/* Incremented whenever something may have been added to dl_loaded. */
|
||||
unsigned long long _dl_load_adds;
|
||||
@@ -79,12 +77,6 @@ unsigned long long _dl_load_adds;
|
||||
main application but here we don't have something like this. So
|
||||
create a fake scope containing nothing. */
|
||||
struct r_scope_elem _dl_initial_searchlist;
|
||||
/* Variable which can be used in lookup to process the global scope. */
|
||||
struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL };
|
||||
/* This is a global pointer to this structure which is public. It is
|
||||
used by dlopen/dlclose to add and remove objects from what is regarded
|
||||
to be the global scope. */
|
||||
struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
|
||||
|
||||
#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Nonzero during startup. */
|
||||
@@ -109,11 +101,6 @@ hp_timing_t _dl_cpuclock_offset;
|
||||
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
|
||||
#endif
|
||||
|
||||
/* This is zero at program start to signal that the global scope map is
|
||||
allocated by rtld. Later it keeps the size of the map. It might be
|
||||
reset if in _dl_close if the last global object is removed. */
|
||||
size_t _dl_global_scope_alloc;
|
||||
|
||||
size_t _dl_pagesize;
|
||||
|
||||
unsigned int _dl_osversion;
|
||||
@@ -149,6 +136,8 @@ int (*_dl_make_stack_executable_hook) (void **) internal_function
|
||||
#ifdef NEED_DL_SYSINFO
|
||||
/* Needed for improved syscall handling on at least x86/Linux. */
|
||||
uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
|
||||
#endif
|
||||
#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
|
||||
/* Address of the ELF headers in the vsyscall page. */
|
||||
const ElfW(Ehdr) *_dl_sysinfo_dso;
|
||||
#endif
|
||||
@@ -196,6 +185,11 @@ _dl_aux_init (ElfW(auxv_t) *av)
|
||||
case AT_SYSINFO:
|
||||
GL(dl_sysinfo) = av->a_un.a_val;
|
||||
break;
|
||||
#endif
|
||||
#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
|
||||
case AT_SYSINFO_EHDR:
|
||||
GL(dl_sysinfo_dso) = av->a_un.a_ptr;
|
||||
break;
|
||||
#endif
|
||||
case AT_UID:
|
||||
uid ^= av->a_un.a_val;
|
||||
@@ -257,22 +251,22 @@ _dl_non_dynamic_init (void)
|
||||
|
||||
if (__libc_enable_secure)
|
||||
{
|
||||
static const char *unsecure_envvars[] =
|
||||
{
|
||||
UNSECURE_ENVVARS,
|
||||
static const char unsecure_envvars[] =
|
||||
UNSECURE_ENVVARS
|
||||
#ifdef EXTRA_UNSECURE_ENVVARS
|
||||
EXTRA_UNSECURE_ENVVARS
|
||||
#endif
|
||||
};
|
||||
size_t cnt;
|
||||
;
|
||||
const char *cp = unsecure_envvars;
|
||||
|
||||
for (cnt = 0;
|
||||
cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]);
|
||||
++cnt)
|
||||
unsetenv (unsecure_envvars[cnt]);
|
||||
while (cp < unsecure_envvars + sizeof (unsecure_envvars))
|
||||
{
|
||||
__unsetenv (cp);
|
||||
cp = (const char *) __rawmemchr (cp, '\0') + 1;
|
||||
}
|
||||
|
||||
if (__access ("/etc/suid-debug", F_OK) != 0)
|
||||
unsetenv ("MALLOC_CHECK_");
|
||||
__unsetenv ("MALLOC_CHECK_");
|
||||
}
|
||||
|
||||
#ifdef DL_PLATFORM_INIT
|
||||
@@ -287,6 +281,11 @@ _dl_non_dynamic_init (void)
|
||||
if (_dl_platform != NULL)
|
||||
_dl_platformlen = strlen (_dl_platform);
|
||||
|
||||
#if defined (__i386__) && !defined (USE_TLS)
|
||||
/* Load libs not using TLS. */
|
||||
_dl_osversion = 0x20205;
|
||||
#endif
|
||||
|
||||
/* Scan for a program header telling us the stack is nonexecutable. */
|
||||
if (_dl_phdr != NULL)
|
||||
for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
|
||||
|
||||
+15
-13
@@ -69,17 +69,19 @@ do_sym (void *handle, const char *name, void *who,
|
||||
|
||||
/* If the address is not recognized the call comes from the main
|
||||
program (we hope). */
|
||||
struct link_map *match = GL(dl_loaded);
|
||||
struct link_map *match = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
/* Find the highest-addressed object that CALLER is not below. */
|
||||
for (struct link_map *l = GL(dl_loaded); l != NULL; l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
|
||||
l = l->l_next)
|
||||
if (caller >= l->l_map_start && caller < l->l_map_end)
|
||||
{
|
||||
/* There must be exactly one DSO for the range of the virtual
|
||||
memory. Otherwise something is really broken. */
|
||||
match = l;
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle == RTLD_DEFAULT)
|
||||
/* Search the global scope. */
|
||||
@@ -88,11 +90,11 @@ do_sym (void *handle, const char *name, void *who,
|
||||
NULL);
|
||||
else if (handle == RTLD_NEXT)
|
||||
{
|
||||
if (__builtin_expect (match == GL(dl_loaded), 0))
|
||||
if (__builtin_expect (match == GL(dl_ns)[LM_ID_BASE]._ns_loaded, 0))
|
||||
{
|
||||
if (! GL(dl_loaded)
|
||||
|| caller < GL(dl_loaded)->l_map_start
|
||||
|| caller >= GL(dl_loaded)->l_map_end)
|
||||
if (match == NULL
|
||||
|| caller < match->l_map_start
|
||||
|| caller >= match->l_map_end)
|
||||
GLRO(dl_signal_error) (0, NULL, NULL, N_("\
|
||||
RTLD_NEXT used in code not dynamically loaded"));
|
||||
}
|
||||
|
||||
+3
-2
@@ -59,7 +59,8 @@ find_needed (const char *name, struct link_map *map)
|
||||
struct link_map *tmap;
|
||||
unsigned int n;
|
||||
|
||||
for (tmap = GL(dl_loaded); tmap != NULL; tmap = tmap->l_next)
|
||||
for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
|
||||
tmap = tmap->l_next)
|
||||
if (_dl_name_match_p (name, tmap))
|
||||
return tmap;
|
||||
|
||||
@@ -243,7 +244,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
|
||||
? map->l_name : rtld_progname),
|
||||
aux->vna_hash,
|
||||
strtab + aux->vna_name,
|
||||
needed, verbose,
|
||||
needed->l_real, verbose,
|
||||
aux->vna_flags & VER_FLG_WEAK);
|
||||
|
||||
/* Compare the version index. */
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ do_lookup_x (const char *undef_name, unsigned long int hash,
|
||||
int num_versions = 0;
|
||||
const ElfW(Sym) *versioned_sym = NULL;
|
||||
|
||||
map = list[i];
|
||||
map = list[i]->l_real;
|
||||
|
||||
/* Here come the extra test needed for `_dl_lookup_symbol_skip'. */
|
||||
if (skip != NULL && map == skip)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* Do relocations for ELF dynamic linking.
|
||||
Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2003, 2004 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
|
||||
@@ -49,7 +49,7 @@
|
||||
relocations; they should be set up to call _dl_runtime_resolve, rather
|
||||
than fully resolved now. */
|
||||
|
||||
static inline void __attribute__ ((always_inline))
|
||||
auto inline void __attribute__ ((always_inline))
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
ElfW(Addr) reladdr, ElfW(Addr) relsize,
|
||||
int lazy)
|
||||
|
||||
+6
-2
@@ -64,8 +64,12 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||
|
||||
|
||||
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
|
||||
|
||||
static inline void __attribute__ ((unused, always_inline))
|
||||
#ifndef RESOLVE
|
||||
static
|
||||
#else
|
||||
auto
|
||||
#endif
|
||||
inline void __attribute__ ((unused, always_inline))
|
||||
elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
{
|
||||
ElfW(Dyn) *dyn = l->l_ld;
|
||||
|
||||
@@ -2402,8 +2402,13 @@ typedef Elf32_Addr Elf32_Conflict;
|
||||
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
|
||||
#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
|
||||
block. */
|
||||
#define R_390_20 57 /* Direct 20 bit. */
|
||||
#define R_390_GOT20 58 /* 20 bit GOT offset. */
|
||||
#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
|
||||
#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
/* Keep this the last entry. */
|
||||
#define R_390_NUM 57
|
||||
#define R_390_NUM 61
|
||||
|
||||
|
||||
/* CRIS relocations. */
|
||||
@@ -2464,6 +2469,35 @@ typedef Elf32_Addr Elf32_Conflict;
|
||||
#define R_X86_64_NUM 24
|
||||
|
||||
|
||||
/* AM33 relocations. */
|
||||
#define R_MN10300_NONE 0 /* No reloc. */
|
||||
#define R_MN10300_32 1 /* Direct 32 bit. */
|
||||
#define R_MN10300_16 2 /* Direct 16 bit. */
|
||||
#define R_MN10300_8 3 /* Direct 8 bit. */
|
||||
#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
|
||||
#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
|
||||
#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
|
||||
#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
|
||||
#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
|
||||
#define R_MN10300_24 9 /* Direct 24 bit. */
|
||||
#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
|
||||
#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
|
||||
#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
|
||||
#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
|
||||
#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
|
||||
#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
|
||||
#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
|
||||
#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
|
||||
#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
|
||||
#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
|
||||
#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
|
||||
#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
|
||||
#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
|
||||
#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
|
||||
|
||||
#define R_MN10300_NUM 24
|
||||
|
||||
|
||||
/* M32R relocs. */
|
||||
#define R_M32R_NONE 0 /* No reloc. */
|
||||
#define R_M32R_16 1 /* Direct 16 bit. */
|
||||
|
||||
+19
-6
@@ -944,17 +944,19 @@ search_dirs (void)
|
||||
|
||||
|
||||
static void parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
bool do_chroot, const char *pattern);
|
||||
const char *prefix, bool do_chroot,
|
||||
const char *pattern);
|
||||
|
||||
/* Parse configuration file. */
|
||||
static void
|
||||
parse_conf (const char *filename, bool do_chroot)
|
||||
parse_conf (const char *filename, const char *prefix, bool do_chroot)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
char *line = NULL;
|
||||
const char *canon;
|
||||
size_t len = 0;
|
||||
unsigned int lineno;
|
||||
size_t prefix_len = prefix ? strlen (prefix) : 0;
|
||||
|
||||
if (do_chroot && opt_chroot)
|
||||
{
|
||||
@@ -1015,7 +1017,14 @@ parse_conf (const char *filename, bool do_chroot)
|
||||
cp += 8;
|
||||
while ((dir = strsep (&cp, " \t")) != NULL)
|
||||
if (dir[0] != '\0')
|
||||
parse_conf_include (filename, lineno, do_chroot, dir);
|
||||
parse_conf_include (filename, lineno, prefix, do_chroot, dir);
|
||||
}
|
||||
else if (prefix != NULL)
|
||||
{
|
||||
size_t cp_len = strlen (cp);
|
||||
char new_cp [prefix_len + cp_len + 1];
|
||||
memcpy (mempcpy (new_cp, prefix, prefix_len), cp, cp_len + 1);
|
||||
add_dir (new_cp);
|
||||
}
|
||||
else
|
||||
add_dir (cp);
|
||||
@@ -1031,7 +1040,7 @@ parse_conf (const char *filename, bool do_chroot)
|
||||
config files to read. */
|
||||
static void
|
||||
parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
bool do_chroot, const char *pattern)
|
||||
const char *prefix, bool do_chroot, const char *pattern)
|
||||
{
|
||||
if (opt_chroot && pattern[0] != '/')
|
||||
error (EXIT_FAILURE, 0,
|
||||
@@ -1061,7 +1070,7 @@ parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
{
|
||||
case 0:
|
||||
for (size_t i = 0; i < gl.gl_pathc; ++i)
|
||||
parse_conf (gl.gl_pathv[i], false);
|
||||
parse_conf (gl.gl_pathv[i], prefix, false);
|
||||
globfree64 (&gl);
|
||||
break;
|
||||
|
||||
@@ -1101,6 +1110,8 @@ main (int argc, char **argv)
|
||||
{
|
||||
int remaining;
|
||||
|
||||
arch_startup (argc, argv);
|
||||
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
||||
@@ -1209,12 +1220,14 @@ main (int argc, char **argv)
|
||||
|
||||
if (!opt_only_cline)
|
||||
{
|
||||
parse_conf (config_file, true);
|
||||
parse_conf (config_file, NULL, true);
|
||||
|
||||
/* Always add the standard search paths. */
|
||||
add_system_dir (SLIBDIR);
|
||||
if (strcmp (SLIBDIR, LIBDIR))
|
||||
add_system_dir (LIBDIR);
|
||||
|
||||
add_arch_dirs (config_file);
|
||||
}
|
||||
|
||||
search_dirs ();
|
||||
|
||||
+26
-5
@@ -105,6 +105,21 @@ add_env="$add_env LD_VERBOSE=$verbose"
|
||||
if test "$unused" = yes; then
|
||||
add_env="$add_env LD_DEBUG=\"$LD_DEBUG${LD_DEBUG:+,}unused\""
|
||||
fi
|
||||
|
||||
# The following use of cat is needed to make ldd work in SELinux
|
||||
# environments where the executed program might not have permissions
|
||||
# to write to the console/tty. But only bash 3.x supports the pipefail
|
||||
# option, and we don't bother to handle the case for older bash versions.
|
||||
if set -o pipefail 2> /dev/null; then
|
||||
try_trace() {
|
||||
eval $add_env '"$@"' | cat
|
||||
}
|
||||
else
|
||||
try_trace() {
|
||||
eval $add_env '"$@"'
|
||||
}
|
||||
fi
|
||||
|
||||
case $# in
|
||||
0)
|
||||
echo >&2 'ldd:' $"missing file arguments"
|
||||
@@ -153,7 +168,16 @@ warning: you do not have execution permission for" "\`$file'" >&2
|
||||
fi
|
||||
case $ret in
|
||||
0)
|
||||
eval $add_env '"$file"' || result=1
|
||||
# If the program exits with exit code 5, it means the process has been
|
||||
# invoked with __libc_enable_secure. Fall back to running it through
|
||||
# the dynamic linker.
|
||||
try_trace "$file"
|
||||
rc=$?
|
||||
if [ $rc = 5 ]; then
|
||||
try_trace "$RTLD" "$file"
|
||||
rc=$?
|
||||
fi
|
||||
[ $rc = 0 ] || result=1
|
||||
;;
|
||||
1)
|
||||
# This can be a non-ELF binary or no binary at all.
|
||||
@@ -163,10 +187,7 @@ warning: you do not have execution permission for" "\`$file'" >&2
|
||||
}
|
||||
;;
|
||||
2)
|
||||
# The following use of cat is needed to make ldd work in SELinux
|
||||
# environments where the executed program might not have permissions
|
||||
# to write to the console/tty.
|
||||
eval $add_env \${RTLD} '"$file"' | cat || result=1
|
||||
try_trace "$RTLD" "$file" || result=1
|
||||
;;
|
||||
*)
|
||||
echo 'ldd:' ${RTLD} $"exited with unknown exit code" "($ret)" >&2
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user