summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile139
-rw-r--r--elf/check-execstack.c162
-rw-r--r--elf/check-localplt.c298
-rw-r--r--elf/check-textrel.c198
-rw-r--r--elf/dl-close.c15
-rw-r--r--elf/dl-deps.c13
-rw-r--r--elf/dl-fini.c8
-rw-r--r--elf/dl-libc.c9
-rw-r--r--elf/dl-load.c5
-rw-r--r--elf/dl-lookup.c3
-rw-r--r--elf/dl-minimal.c40
-rw-r--r--elf/dl-open.c8
-rw-r--r--elf/dl-reloc.c6
-rw-r--r--elf/dl-support.c6
-rw-r--r--elf/dl-sysdep.c15
-rw-r--r--elf/dynamic-link.h69
-rw-r--r--elf/elf.h4
-rw-r--r--elf/ldconfig.c6
-rw-r--r--elf/pldd-xx.c18
-rw-r--r--elf/rtld-Rules5
-rw-r--r--elf/rtld.c28
-rw-r--r--elf/stackguard-macros.h30
-rw-r--r--elf/tls-macros.h16
-rw-r--r--elf/tst-auditmod1.c2
-rw-r--r--elf/tst-auditmod3b.c2
-rw-r--r--elf/tst-auditmod4b.c2
-rw-r--r--elf/tst-auditmod5b.c2
-rw-r--r--elf/tst-auditmod6b.c2
-rw-r--r--elf/tst-auditmod6c.c2
-rw-r--r--elf/tst-auditmod7b.c2
-rw-r--r--elf/tst-execstack.c71
-rw-r--r--elf/tst-relsort1.c2
32 files changed, 311 insertions, 877 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 59a3936a1b..0c26ce545a 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2011, 2012 Free Software Foundation, Inc.
+# Copyright (C) 1995-2012 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
@@ -80,15 +80,14 @@ install-rootsbin += ldconfig
ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon
extra-objs += $(ldconfig-modules:=.o)
+endif
+endif
pldd-modules := xmalloc
# To find xmalloc.c and xstrdup.c
vpath %.c ../locale/programs
-endif
-endif
-
ifeq ($(have-ksh)$(build-shared),yesyes)
extra-objs += sotruss-lib.os sotruss-lib.so
install-others += $(inst_auditdir)/sotruss-lib.so
@@ -156,7 +155,9 @@ tests += tst-audit6 tst-audit7
endif
endif
endif
+ifeq ($(cross-compiling),no)
tests: $(objpfx)tst-leaks1-mem $(objpfx)noload-mem
+endif
tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
tlsmod17a-modules = $(addprefix tst-tlsmod17a, $(tlsmod17a-suffixes))
@@ -419,8 +420,10 @@ CFLAGS-ldconfig.c = $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \
-D'SLIBDIR="$(slibdir)"' -DIS_IN_ldconfig=1
CFLAGS-dl-cache.c = $(SYSCONF-FLAGS)
CFLAGS-cache.c = $(SYSCONF-FLAGS)
+CFLAGS-rtld.c = $(SYSCONF-FLAGS)
-CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),-DNOT_IN_libc=1 -DIS_IN_rtld=1)
+CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
+ -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld)
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(strip $(modules-names))))
generated += $(addsuffix .so,$(strip $(modules-names)))
@@ -497,6 +500,18 @@ $(objpfx)tst-initordera3.so: $(objpfx)tst-initorderb2.so $(objpfx)tst-initorderb
$(objpfx)tst-initordera4.so: $(objpfx)tst-initordera3.so
$(objpfx)tst-initorder: $(objpfx)tst-initordera4.so $(objpfx)tst-initordera1.so $(objpfx)tst-initorderb2.so
+LDFLAGS-nodel2mod3.so = $(no-as-needed)
+LDFLAGS-reldepmod5.so = $(no-as-needed)
+LDFLAGS-reldep6mod1.so = $(no-as-needed)
+LDFLAGS-reldep6mod4.so = $(no-as-needed)
+LDFLAGS-reldep8mod3.so = $(no-as-needed)
+LDFLAGS-unload4mod1.so = $(no-as-needed)
+LDFLAGS-unload4mod2.so = $(no-as-needed)
+LDFLAGS-tst-initorder = $(no-as-needed)
+LDFLAGS-tst-initordera2.so = $(no-as-needed)
+LDFLAGS-tst-initordera3.so = $(no-as-needed)
+LDFLAGS-tst-initordera4.so = $(no-as-needed)
+LDFLAGS-tst-initorderb2.so = $(no-as-needed)
LDFLAGS-tst-tlsmod5.so = -nostdlib
LDFLAGS-tst-tlsmod6.so = -nostdlib
@@ -630,7 +645,7 @@ $(objpfx)vismain.out: $(addprefix $(objpfx),vismod3.so)
vismain-ENV = LD_PRELOAD=$(addprefix $(objpfx),vismod3.so)
$(objpfx)noload: $(objpfx)testobj1.so $(common-objpfx)dlfcn/libdl.so
-LDFLAGS-noload = -rdynamic
+LDFLAGS-noload = -rdynamic $(no-as-needed)
$(objpfx)noload.out: $(objpfx)testobj5.so
$(objpfx)noload-mem: $(objpfx)noload.out
@@ -675,6 +690,7 @@ $(objpfx)reldep4: $(libdl)
$(objpfx)reldep4.out: $(objpfx)reldep4mod1.so $(objpfx)reldep4mod2.so
$(objpfx)next: $(objpfx)nextmod1.so $(objpfx)nextmod2.so $(libdl)
+LDFLAGS-next = $(no-as-needed)
$(objpfx)unload2: $(libdl)
$(objpfx)unload2.out: $(objpfx)unload2mod.so $(objpfx)unload2dep.so
@@ -869,45 +885,64 @@ CFLAGS-tst-pie1.c += $(pie-ccflag)
$(objpfx)tst-pie1: $(objpfx)tst-piemod1.so
-check-textrel-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
-$(objpfx)check-textrel: check-textrel.c
- $(native-compile)
+ifeq (yes,$(build-shared))
+tests: $(objpfx)check-textrel.out $(objpfx)check-execstack.out
-check-execstack-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -std=gnu99 \
- $(objpfx:%/=-I%)
-$(objpfx)check-execstack: check-execstack.c $(objpfx)check-execstack.h
- $(native-compile)
-$(objpfx)check-execstack.h: $(first-word $(wildcard $(sysdirs:%=%/stackinfo.h)))
- $(make-target-directory)
- { echo '#include <stackinfo.h>'; echo '@@@DEFAULT_STACK_PERMS@@@'; } | \
- $(CC) $(CFLAGS) $(CPPFLAGS) -E -x c-header - | \
- sed -n -e 's/^@@@\(.*\)@@@/#define DEFAULT_STACK_PERMS \1/p' > $@T
- mv -f $@T $@
-generated += check-execstack.h
+all-built-dso := $(common-objpfx)libc.so \
+ $(filter-out $(common-objpfx)linkobj/libc.so, \
+ $(sort $(wildcard $(addprefix $(common-objpfx), \
+ */lib*.so \
+ iconvdata/*.so))))
-check-localplt-CFLAGS = -O -Wall -D_GNU_SOURCE -std=gnu99
-$(objpfx)check-localplt: check-localplt.c
- $(native-compile)
+$(all-built-dso:=.dyn): %.dyn: %
+ @rm -f $@T
+ LC_ALL=C $(READELF) -W -d $< > $@T
+ test -s $@T
+ mv -f $@T $@
+common-generated += $(all-built-dso:$(common-objpfx)%=%.dyn)
-ifeq (yes,$(build-shared))
-tests: $(objpfx)check-textrel.out $(objpfx)check-execstack.out
+$(objpfx)check-textrel.out: $(..)scripts/check-textrel.awk \
+ $(all-built-dso:=.dyn)
+ LC_ALL=C $(AWK) -f $^ > $@
+generated += check-textrel.out
-all-built-dso = $(common-objpfx)libc.so \
- $(filter-out $(common-objpfx)linkobj/libc.so, \
- $(sort $(wildcard $(common-objpfx)*/lib*.so \
- $(common-objpfx)iconvdata/*.so)))
+$(objpfx)execstack-default: $(first-word $(wildcard $(sysdirs:%=%/stackinfo.h)))
+ $(make-target-directory)
+ { echo '#include <elf.h>'; \
+ echo '#include <stackinfo.h>'; \
+ echo '#if (DEFAULT_STACK_PERMS & PF_X) == 0'; \
+ echo '@@@execstack-no@@@'; \
+ echo '#else'; \
+ echo '@@@execstack-yes@@@'; \
+ echo '#endif'; } | \
+ $(CC) $(CFLAGS) $(CPPFLAGS) -E -x c-header - | \
+ sed -n -e 's/^@@@\(.*\)@@@/\1/p' > $@T
+ mv -f $@T $@
+generated += execstack-default
-$(objpfx)check-textrel.out: $(objpfx)check-textrel $(all-built-dso)
- $(dir $<)$(notdir $<) $(filter-out $<, $^) > $@
-generated += check-textrel check-textrel.out
+$(all-built-dso:=.phdr): %.phdr: %
+ @rm -f $@T
+ LC_ALL=C $(READELF) -W -l $< > $@T
+ test -s $@T
+ mv -f $@T $@
+common-generated += $(all-built-dso:$(common-objpfx)%=%.phdr)
-$(objpfx)check-execstack.out: $(objpfx)check-execstack $(all-built-dso)
- $(dir $<)$(notdir $<) $(filter-out $<, $^) > $@
-generated += check-execstack check-execstack.out
+$(objpfx)check-execstack.out: $(..)scripts/check-execstack.awk \
+ $(objpfx)execstack-default \
+ $(all-built-dso:=.phdr)
+ LC_ALL=C $(AWK) -f $^ > $@
+generated += check-execstack.out
$(objpfx)tst-dlmodcount: $(libdl)
$(objpfx)tst-dlmodcount.out: $(test-modules)
+$(all-built-dso:=.jmprel): %.jmprel: % Makefile
+ @rm -f $@T
+ LC_ALL=C $(READELF) -W -S -d -r $< > $@T
+ test -s $@T
+ mv -f $@T $@
+common-generated += $(all-built-dso:$(common-objpfx)%=%.jmprel)
+
check-data := $(firstword $(wildcard \
$(foreach D,$(add-ons) scripts,\
$(patsubst %,$(..)$D/data/localplt-%.data,\
@@ -919,21 +954,25 @@ check-data := $(firstword $(wildcard \
tests: $(objpfx)check-localplt.out
+localplt-built-dso := $(addprefix $(common-objpfx),\
+ libc.so \
+ math/libm.so \
+ rt/librt.so \
+ dlfcn/libdl.so \
+ resolv/libresolv.so \
+ crypt/libcrypt.so \
+ )
ifeq ($(have-thread-library),yes)
-thread-dso := $(filter-out %_nonshared.a, $(shared-thread-library))
+localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
endif
-$(objpfx)check-localplt.out: $(objpfx)check-localplt \
- $(common-objpfx)libc.so \
- $(common-objpfx)math/libm.so $(thread-dso) \
- $(common-objpfx)rt/librt.so \
- $(common-objpfx)dlfcn/libdl.so \
- $(common-objpfx)resolv/libresolv.so \
- $(common-objpfx)crypt/libcrypt.so \
+$(objpfx)check-localplt.out: $(..)scripts/check-localplt.awk \
+ $(..)scripts/localplt.awk \
+ $(localplt-built-dso:=.jmprel) \
$(check-data)
- $(dir $<)$(notdir $<) $(filter-out $< $(check-data),$^) | \
- LC_ALL=C sort | \
- diff -u $(check-data) - > $@
+ LC_ALL=C $(AWK) -f $(filter-out $< $(check-data),$^) | \
+ LC_ALL=C $(AWK) -f $< $(check-data) - \
+ > $@
endif
$(objpfx)tst-dlopenrpathmod.so: $(libdl)
@@ -999,6 +1038,8 @@ $(objpfx)order2mod1.so: $(objpfx)order2mod4.so
$(objpfx)order2mod4.so: $(objpfx)order2mod3.so
$(objpfx)order2mod2.so: $(objpfx)order2mod3.so
order2mod2.so-no-z-defs = yes
+LDFLAGS-order2mod1.so = $(no-as-needed)
+LDFLAGS-order2mod2.so = $(no-as-needed)
tst-stackguard1-ARGS = --command "$(built-program-cmd) --child"
tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
@@ -1087,6 +1128,10 @@ $(objpfx)tst-initorder2: $(objpfx)tst-initorder2a.so $(objpfx)tst-initorder2d.so
$(objpfx)tst-initorder2a.so: $(objpfx)tst-initorder2b.so
$(objpfx)tst-initorder2b.so: $(objpfx)tst-initorder2c.so
$(objpfx)tst-initorder2c.so: $(objpfx)tst-initorder2d.so
+LDFLAGS-tst-initorder2 = $(no-as-needed)
+LDFLAGS-tst-initorder2a.so = $(no-as-needed)
+LDFLAGS-tst-initorder2b.so = $(no-as-needed)
+LDFLAGS-tst-initorder2c.so = $(no-as-needed)
define o-iterator-doit
$(objpfx)tst-initorder2$o.os: tst-initorder2.c; \
$$(compile-command.c) -DNAME=\"$o\"
@@ -1119,7 +1164,9 @@ $(objpfx)tst-relsort1mod2.so: $(libm)
$(objpfx)tst-relsort1.out: $(objpfx)tst-relsort1mod1.so \
$(objpfx)tst-relsort1mod2.so
+ifeq ($(cross-compiling),no)
tests: $(objpfx)tst-unused-dep.out
+endif
$(objpfx)tst-unused-dep.out: $(objpfx)testobj1.so
LD_TRACE_LOADED_OBJECTS=1 \
diff --git a/elf/check-execstack.c b/elf/check-execstack.c
deleted file mode 100644
index 6a5c4d9b9a..0000000000
--- a/elf/check-execstack.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Check for executable stacks in DSOs.
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contribute by Ulrich Drepper <drepper@redhat.com>. 2009.
-
- 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <byteswap.h>
-#include <elf.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "check-execstack.h"
-
-
-#ifdef BITS
-
-# define AB(name) _AB (name, BITS)
-# define _AB(name, bits) __AB (name, bits)
-# define __AB(name, bits) name##bits
-# define E(name) _E (name, BITS)
-# define _E(name, bits) __E (name, bits)
-# define __E(name, bits) Elf##bits##_##name
-# define SWAP(val) \
- ({ __typeof (val) __res; \
- if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB \
- && BYTE_ORDER == LITTLE_ENDIAN) \
- || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB \
- && BYTE_ORDER == BIG_ENDIAN)) \
- && sizeof (val) != 1) \
- { \
- if (sizeof (val) == 2) \
- __res = bswap_16 (val); \
- else if (sizeof (val) == 4) \
- __res = bswap_32 (val); \
- else \
- __res = bswap_64 (val); \
- } \
- else \
- __res = (val); \
- __res; })
-
-
-static int
-AB(handle_file) (const char *fname, int fd)
-{
- E(Ehdr) ehdr;
-
- if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
- {
- read_error:
- printf ("%s: read error: %m\n", fname);
- return 1;
- }
-
- const size_t phnum = SWAP (ehdr.e_phnum);
- const size_t phentsize = SWAP (ehdr.e_phentsize);
-
- /* Read the program header. */
- E(Phdr) *phdr = alloca (phentsize * phnum);
- if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
- != phentsize * phnum)
- goto read_error;
-
- /* Search for the PT_GNU_STACK entry. */
- for (size_t cnt = 0; cnt < phnum; ++cnt)
- if (SWAP (phdr[cnt].p_type) == PT_GNU_STACK)
- {
- unsigned int flags = SWAP(phdr[cnt].p_flags);
- if (flags & PF_X)
- {
- printf ("%s: executable stack signaled\n", fname);
- return 1;
- }
-
- return 0;
- }
-
- if (DEFAULT_STACK_PERMS & PF_X)
- {
- printf ("%s: no PT_GNU_STACK entry\n", fname);
- return 1;
- }
-
- return 0;
-}
-
-# undef BITS
-#else
-
-# define BITS 32
-# include "check-execstack.c"
-
-# define BITS 64
-# include "check-execstack.c"
-
-
-static int
-handle_file (const char *fname)
-{
- int fd = open (fname, O_RDONLY);
- if (fd == -1)
- {
- printf ("cannot open %s: %m\n", fname);
- return 1;
- }
-
- /* Read was is supposed to be the ELF header. Read the initial
- bytes to determine whether this is a 32 or 64 bit file. */
- char ident[EI_NIDENT];
- if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
- {
- printf ("%s: read error: %m\n", fname);
- close (fd);
- return 1;
- }
-
- if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
- {
- printf ("%s: not an ELF file\n", fname);
- close (fd);
- return 1;
- }
-
- int result;
- if (ident[EI_CLASS] == ELFCLASS64)
- result = handle_file64 (fname, fd);
- else
- result = handle_file32 (fname, fd);
-
- close (fd);
-
- return result;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- int cnt;
- int result = 0;
-
- for (cnt = 1; cnt < argc; ++cnt)
- result |= handle_file (argv[cnt]);
- return result;
-}
-#endif
diff --git a/elf/check-localplt.c b/elf/check-localplt.c
deleted file mode 100644
index edab1d2d0a..0000000000
--- a/elf/check-localplt.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Show local PLT use in DSOs.
- Copyright (C) 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contribute by Ulrich Drepper <drepper@redhat.com>. 2006.
-
- 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <byteswap.h>
-#include <elf.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-#ifdef BITS
-
-# define AB(name) _AB (name, BITS)
-# define _AB(name, bits) __AB (name, bits)
-# define __AB(name, bits) name##bits
-# define E(name) _E (name, BITS)
-# define _E(name, bits) __E (name, bits)
-# define __E(name, bits) Elf##bits##_##name
-# define EE(name) _EE (name, BITS)
-# define _EE(name, bits) __EE (name, bits)
-# define __EE(name, bits) ELF##bits##_##name
-# define SWAP(val) \
- ({ __typeof (val) __res; \
- if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB \
- && BYTE_ORDER == LITTLE_ENDIAN) \
- || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB \
- && BYTE_ORDER == BIG_ENDIAN)) \
- && sizeof (val) != 1) \
- { \
- if (sizeof (val) == 2) \
- __res = bswap_16 (val); \
- else if (sizeof (val) == 4) \
- __res = bswap_32 (val); \
- else \
- __res = bswap_64 (val); \
- } \
- else \
- __res = (val); \
- __res; })
-
-
-static int
-AB(handle_file) (const char *fname, int fd)
-{
- E(Ehdr) ehdr;
-
- if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
- {
- read_error:
- printf ("%s: read error: %m\n", fname);
- return 1;
- }
-
- const size_t phnum = SWAP (ehdr.e_phnum);
- const size_t phentsize = SWAP (ehdr.e_phentsize);
-
- /* Read the program header. */
- E(Phdr) *phdr = alloca (phentsize * phnum);
- if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
- != phentsize * phnum)
- goto read_error;
-
- /* Search for the PT_DYNAMIC entry. */
- size_t cnt;
- E(Phdr) *dynphdr = NULL;
- for (cnt = 0; cnt < phnum; ++cnt)
- if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC)
- {
- dynphdr = &phdr[cnt];
- break;
- }
-
- if (dynphdr == NULL)
- {
- printf ("%s: no DYNAMIC segment found\n", fname);
- return 1;
- }
-
- /* Read the dynamic segment. */
- size_t pmemsz = SWAP(dynphdr->p_memsz);
- E(Dyn) *dyn = alloca (pmemsz);
- if (pread64 (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz)
- goto read_error;
-
- /* Search for an DT_PLTREL, DT_JMPREL, DT_PLTRELSZ, DT_STRTAB,
- DT_STRSZ, and DT_SYMTAB entries. */
- size_t pltrel_idx = SIZE_MAX;
- size_t jmprel_idx = SIZE_MAX;
- size_t pltrelsz_idx = SIZE_MAX;
- size_t strtab_idx = SIZE_MAX;
- size_t strsz_idx = SIZE_MAX;
- size_t symtab_idx = SIZE_MAX;
- for (cnt = 0; (cnt + 1) * sizeof (E(Dyn)) - 1 < pmemsz; ++cnt)
- {
- unsigned int tag = SWAP (dyn[cnt].d_tag);
-
- if (tag == DT_NULL)
- /* We reached the end. */
- break;
-
- if (tag == DT_PLTREL)
- pltrel_idx = cnt;
- else if (tag == DT_JMPREL)
- jmprel_idx = cnt;
- else if (tag == DT_PLTRELSZ)
- pltrelsz_idx = cnt;
- else if (tag == DT_STRTAB)
- strtab_idx = cnt;
- else if (tag == DT_STRSZ)
- strsz_idx = cnt;
- else if (tag == DT_SYMTAB)
- symtab_idx = cnt;
- }
-
- if (pltrel_idx == SIZE_MAX || jmprel_idx == SIZE_MAX
- || pltrelsz_idx == SIZE_MAX || strtab_idx == SIZE_MAX
- || strsz_idx == SIZE_MAX || symtab_idx == SIZE_MAX)
- {
- puts ("not all PLT information found");
- return 1;
- }
-
- E(Xword) relsz = SWAP (dyn[pltrelsz_idx].d_un.d_val);
-
- void *relmem = NULL;
- char *strtab = NULL;
- E(Xword) symtab_offset = 0;
-
- /* Find the offset of DT_JMPREL and load the data. */
- for (cnt = 0; cnt < phnum; ++cnt)
- if (SWAP (phdr[cnt].p_type) == PT_LOAD)
- {
- E(Addr) vaddr = SWAP (phdr[cnt].p_vaddr);
- E(Xword) memsz = SWAP (phdr[cnt].p_memsz);
-
- if (vaddr <= SWAP (dyn[jmprel_idx].d_un.d_val)
- && vaddr + memsz >= SWAP (dyn[jmprel_idx].d_un.d_val) + relsz)
- {
- relmem = alloca (SWAP (dyn[pltrelsz_idx].d_un.d_val));
- if (pread64 (fd, relmem, relsz,
- SWAP (phdr[cnt].p_offset)
- + SWAP (dyn[jmprel_idx].d_un.d_val) - vaddr)
- != relsz)
- {
- puts ("cannot read JMPREL");
- return 1;
- }
- }
-
- if (vaddr <= SWAP (dyn[symtab_idx].d_un.d_val)
- && vaddr + memsz > SWAP (dyn[symtab_idx].d_un.d_val))
- symtab_offset = (SWAP (phdr[cnt].p_offset)
- + SWAP (dyn[symtab_idx].d_un.d_val) - vaddr);
-
- if (vaddr <= SWAP (dyn[strtab_idx].d_un.d_val)
- && vaddr + memsz >= (SWAP (dyn[strtab_idx].d_un.d_val)
- + SWAP(dyn[strsz_idx].d_un.d_val)))
- {
- strtab = alloca (SWAP(dyn[strsz_idx].d_un.d_val));
- if (pread64 (fd, strtab, SWAP(dyn[strsz_idx].d_un.d_val),
- SWAP (phdr[cnt].p_offset)
- + SWAP (dyn[strtab_idx].d_un.d_val) - vaddr)
- != SWAP(dyn[strsz_idx].d_un.d_val))
- {
- puts ("cannot read STRTAB");
- return 1;
- }
- }
- }
-
- if (relmem == NULL || strtab == NULL || symtab_offset == 0)
- {
- puts ("couldn't load PLT data");
- return 1;
- }
-
- if (SWAP (dyn[pltrel_idx].d_un.d_val) == DT_RELA)
- for (E(Rela) *rela = relmem; (char *) rela - (char *) relmem < relsz;
- ++rela)
- {
- E(Sym) sym;
-
- if (pread64 (fd, &sym, sizeof (sym),
- symtab_offset
- + EE(R_SYM) (SWAP (rela->r_info)) * sizeof (sym))
- != sizeof (sym))
- {
- puts ("cannot read symbol");
- return 1;
- }
-
- if (sym.st_value != 0)
- /* This symbol is locally defined. */
- printf ("%s: %s\n", basename (fname), strtab + SWAP (sym.st_name));
- }
- else
- for (E(Rel) *rel = relmem; (char *) rel - (char *) relmem < relsz; ++rel)
- {
- E(Sym) sym;
-
- if (pread64 (fd, &sym, sizeof (sym),
- symtab_offset
- + EE(R_SYM) (SWAP (rel->r_info)) * sizeof (sym))
- != sizeof (sym))
- {
- puts ("cannot read symbol");
- return 1;
- }
-
- if (sym.st_value != 0)
- /* This symbol is locally defined. */
- printf ("%s: %s\n", basename (fname), strtab + SWAP (sym.st_name));
- }
-
- return 0;
-}
-
-# undef BITS
-#else
-
-# define BITS 32
-# include "check-localplt.c"
-
-# define BITS 64
-# include "check-localplt.c"
-
-
-static int
-handle_file (const char *fname)
-{
- int fd = open (fname, O_RDONLY);
- if (fd == -1)
- {
- printf ("cannot open %s: %m\n", fname);
- return 1;
- }
-
- /* Read was is supposed to be the ELF header. Read the initial
- bytes to determine whether this is a 32 or 64 bit file. */
- char ident[EI_NIDENT];
- if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
- {
- printf ("%s: read error: %m\n", fname);
- close (fd);
- return 1;
- }
-
- if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
- {
- printf ("%s: not an ELF file\n", fname);
- close (fd);
- return 1;
- }
-
- int result;
- if (ident[EI_CLASS] == ELFCLASS64)
- result = handle_file64 (fname, fd);
- else
- result = handle_file32 (fname, fd);
-
- close (fd);
-
- return result;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- int cnt;
- int result = 0;
-
- for (cnt = 1; cnt < argc; ++cnt)
- result |= handle_file (argv[cnt]);
-
- return result;
-}
-#endif
diff --git a/elf/check-textrel.c b/elf/check-textrel.c
deleted file mode 100644
index 6372019a9c..0000000000
--- a/elf/check-textrel.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* Check for text relocations in DSOs.
- Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contribute by Ulrich Drepper <drepper@redhat.com>. 2002.
-
- 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <byteswap.h>
-#include <elf.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-#ifdef BITS
-
-# define AB(name) _AB (name, BITS)
-# define _AB(name, bits) __AB (name, bits)
-# define __AB(name, bits) name##bits
-# define E(name) _E (name, BITS)
-# define _E(name, bits) __E (name, bits)
-# define __E(name, bits) Elf##bits##_##name
-# define SWAP(val) \
- ({ __typeof (val) __res; \
- if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB \
- && BYTE_ORDER == LITTLE_ENDIAN) \
- || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB \
- && BYTE_ORDER == BIG_ENDIAN)) \
- && sizeof (val) != 1) \
- { \
- if (sizeof (val) == 2) \
- __res = bswap_16 (val); \
- else if (sizeof (val) == 4) \
- __res = bswap_32 (val); \
- else \
- __res = bswap_64 (val); \
- } \
- else \
- __res = (val); \
- __res; })
-
-
-static int
-AB(handle_file) (const char *fname, int fd)
-{
- E(Ehdr) ehdr;
-
- if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
- {
- read_error:
- printf ("%s: read error: %m\n", fname);
- return 1;
- }
-
- const size_t phnum = SWAP (ehdr.e_phnum);
- const size_t phentsize = SWAP (ehdr.e_phentsize);
-
- /* Read the program header. */
- E(Phdr) *phdr = alloca (phentsize * phnum);
- if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
- != phentsize * phnum)
- goto read_error;
-
- /* Search for the PT_DYNAMIC entry. */
- size_t cnt;
- E(Phdr) *dynphdr = NULL;
- for (cnt = 0; cnt < phnum; ++cnt)
- if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC)
- dynphdr = &phdr[cnt];
- else if (SWAP (phdr[cnt].p_type) == PT_LOAD
- && (SWAP (phdr[cnt].p_flags) & (PF_X | PF_W)) == (PF_X | PF_W))
- {
- printf ("%s: segment %zu is executable and writable\n",
- fname, cnt);
-#if !defined __sparc__ \
- && !defined __alpha__ \
- && (!defined __powerpc__ || defined __powerpc64__ || defined HAVE_PPC_SECURE_PLT)
- /* sparc, sparc64, alpha and powerpc32 (the last one only when using
- -mbss-plt) are expected to have PF_X | PF_W segment containing .plt
- section, it is part of their ABI. It is bad security wise, nevertheless
- this test shouldn't fail because of this. */
- return 1;
-#endif
- }
-
- if (dynphdr == NULL)
- {
- printf ("%s: no DYNAMIC segment found\n", fname);
- return 1;
- }
-
- /* Read the dynamic segment. */
- size_t pmemsz = SWAP(dynphdr->p_memsz);
- E(Dyn) *dyn = alloca (pmemsz);
- if (pread (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz)
- goto read_error;
-
- /* Search for an DT_TEXTREL entry of DT_FLAGS with the DF_TEXTREL
- bit set. */
- for (cnt = 0; (cnt + 1) * sizeof (E(Dyn)) - 1 < pmemsz; ++cnt)
- {
- unsigned int tag = SWAP (dyn[cnt].d_tag);
-
- if (tag == DT_NULL)
- /* We reached the end. */
- break;
-
- if (tag == DT_TEXTREL
- || (tag == DT_FLAGS
- && (SWAP (dyn[cnt].d_un.d_val) & DF_TEXTREL) != 0))
- {
- /* Urgh! The DSO has text relocations. */
- printf ("%s: text relocations used\n", fname);
- return 1;
- }
- }
-
- printf ("%s: OK\n", fname);
-
- return 0;
-}
-
-# undef BITS
-#else
-
-# define BITS 32
-# include "check-textrel.c"
-
-# define BITS 64
-# include "check-textrel.c"
-
-
-static int
-handle_file (const char *fname)
-{
- int fd = open (fname, O_RDONLY);
- if (fd == -1)
- {
- printf ("cannot open %s: %m\n", fname);
- return 1;
- }
-
- /* Read was is supposed to be the ELF header. Read the initial
- bytes to determine whether this is a 32 or 64 bit file. */
- char ident[EI_NIDENT];
- if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
- {
- printf ("%s: read error: %m\n", fname);
- close (fd);
- return 1;
- }
-
- if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
- {
- printf ("%s: not an ELF file\n", fname);
- close (fd);
- return 1;
- }
-
- int result;
- if (ident[EI_CLASS] == ELFCLASS64)
- result = handle_file64 (fname, fd);
- else
- result = handle_file32 (fname, fd);
-
- close (fd);
-
- return result;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- int cnt;
- int result = 0;
-
- for (cnt = 1; cnt < argc; ++cnt)
- result |= handle_file (argv[cnt]);
-
- return result;
-}
-#endif
diff --git a/elf/dl-close.c b/elf/dl-close.c
index d232294665..a250ea5e3e 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -1,5 +1,5 @@
/* Close a shared object opened by `_dl_open'.
- Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1996-2012 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
@@ -118,17 +118,8 @@ _dl_close_worker (struct link_map *map)
if (map->l_direct_opencount > 0 || map->l_type != lt_loaded
|| dl_close_state != not_pending)
{
- if (map->l_direct_opencount == 0)
- {
- if (map->l_type == lt_loaded)
- dl_close_state = rerun;
- else if (map->l_type == lt_library)
- {
- struct link_map **oldp = map->l_initfini;
- map->l_initfini = map->l_orig_initfini;
- _dl_scope_free (oldp);
- }
- }
+ if (map->l_direct_opencount == 0 && map->l_type == lt_loaded)
+ dl_close_state = rerun;
/* There are still references to this object. Do nothing more. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index fb1c3058c0..2ae496d7b5 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -1,6 +1,5 @@
/* Load the dependencies of a mapped object.
- Copyright (C) 1996-2003, 2004, 2005, 2006, 2007, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2012 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
@@ -488,6 +487,7 @@ _dl_map_object_deps (struct link_map *map,
nneeded * sizeof needed[0]);
atomic_write_barrier ();
l->l_initfini = l_initfini;
+ l->l_free_initfini = 1;
}
/* If we have no auxiliary objects just go on to the next map. */
@@ -632,7 +632,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
/* We can skip looking for the binary itself which is at the front
of the search list. */
i = 1;
- char seen[nlist];
+ uint16_t seen[nlist];
memset (seen, 0, nlist * sizeof (seen[0]));
while (1)
{
@@ -658,13 +658,13 @@ Filters not supported with LD_TRACE_PRELINKING"));
(k - i) * sizeof (l_initfini[0]));
l_initfini[k] = thisp;
- if (seen[i + 1] > 1)
+ if (seen[i + 1] > nlist - i)
{
++i;
goto next_clear;
}
- char this_seen = seen[i];
+ uint16_t this_seen = seen[i];
memmove (&seen[i], &seen[i + 1],
(k - i) * sizeof (seen[0]));
seen[k] = this_seen;
@@ -688,6 +688,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
l_initfini[nlist] = NULL;
atomic_write_barrier ();
map->l_initfini = l_initfini;
+ map->l_free_initfini = 1;
if (l_reldeps != NULL)
{
atomic_write_barrier ();
@@ -696,7 +697,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
_dl_scope_free (old_l_reldeps);
}
if (old_l_initfini != NULL)
- map->l_orig_initfini = old_l_initfini;
+ _dl_scope_free (old_l_initfini);
if (errno_reason)
_dl_signal_error (errno_reason == -1 ? 0 : errno_reason, objname,
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 05146b3795..87cf2f1d33 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -1,5 +1,5 @@
/* Call the termination functions of loaded shared objects.
- Copyright (C) 1995,96,1998-2002,2004-2005,2009,2011
+ Copyright (C) 1995, 1996, 1998-2002, 2004-2005, 2009, 2011-2012
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -38,7 +38,7 @@ _dl_sort_fini (struct link_map **maps, size_t nmaps, char *used, Lmid_t ns)
/* We can skip looking for the binary itself which is at the front
of the search list for the main namespace. */
unsigned int i = ns == LM_ID_BASE;
- char seen[nmaps];
+ uint16_t seen[nmaps];
memset (seen, 0, nmaps * sizeof (seen[0]));
while (1)
{
@@ -78,13 +78,13 @@ _dl_sort_fini (struct link_map **maps, size_t nmaps, char *used, Lmid_t ns)
used[k] = here_used;
}
- if (seen[i + 1] > 1)
+ if (seen[i + 1] > nmaps - i)
{
++i;
goto next_clear;
}
- char this_seen = seen[i];
+ uint16_t this_seen = seen[i];
memmove (&seen[i], &seen[i + 1], (k - i) * sizeof (seen[0]));
seen[k] = this_seen;
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index a58e2164f6..af2e663737 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -1,6 +1,5 @@
/* Handle loading and unloading shared objects for internal libc purposes.
- Copyright (C) 1999-2002,2004-2006,2009,2010,2011
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.
@@ -269,13 +268,13 @@ libc_freeres_fn (free_mem)
for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
{
- /* Remove all additional names added to the objects. */
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;
+ /* Remove all additional names added to the objects. */
while (lnp != NULL)
{
struct libname_list *old = lnp;
@@ -283,6 +282,10 @@ libc_freeres_fn (free_mem)
if (! old->dont_free)
free (old);
}
+
+ /* Free the initfini dependency list. */
+ if (l->l_free_initfini)
+ free (l->l_initfini);
}
if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 41d48ee138..fe83f87eb9 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1,5 +1,5 @@
/* Map in a shared object's segments from the file.
- Copyright (C) 1995-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 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
@@ -2194,7 +2194,8 @@ _dl_map_object (struct link_map *loader, const char *name,
if (fd == -1
&& (__builtin_expect (! (mode & __RTLD_SECURE), 1)
- || ! INTUSE(__libc_enable_secure)))
+ || ! INTUSE(__libc_enable_secure))
+ && __builtin_expect (GLRO(dl_inhibit_cache) == 0, 1))
{
/* Check the list of libraries in the file /etc/ld.so.cache,
for compatibility with Linux's ldconfig program. */
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 839dd3a4fc..a2a699b48f 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -769,7 +769,8 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
if (__builtin_expect (current_value.s == NULL, 0))
{
if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
- && skip_map == NULL)
+ && skip_map == NULL
+ && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
{
/* We could find no value for a strong reference. */
const char *reference_name = undef_map ? undef_map->l_name : "";
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c
index 316de99b8f..a8b2d4f339 100644
--- a/elf/dl-minimal.c
+++ b/elf/dl-minimal.c
@@ -1,6 +1,5 @@
/* Minimal replacements for basic facilities used in the dynamic linker.
- Copyright (C) 1995-1998,2000-2002,2004-2006,2007,2009
- Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 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
@@ -232,6 +231,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
{
unsigned long int result = 0;
long int sign = 1;
+ unsigned max_digit;
while (*nptr == ' ' || *nptr == '\t')
++nptr;
@@ -253,6 +253,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
assert (base == 0);
base = 10;
+ max_digit = 9;
if (*nptr == '0')
{
if (nptr[1] == 'x' || nptr[1] == 'X')
@@ -261,14 +262,31 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
nptr += 2;
}
else
- base = 8;
+ {
+ base = 8;
+ max_digit = 7;
+ }
}
- while (*nptr >= '0' && *nptr <= '9')
+ while (1)
{
- unsigned long int digval = *nptr - '0';
- if (result > ULONG_MAX / 10
- || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10))
+ unsigned long int digval;
+ if (*nptr >= '0' && *nptr <= '0' + max_digit)
+ digval = *nptr - '0';
+ else if (base == 16)
+ {
+ if (*nptr >= 'a' && *nptr <= 'f')
+ digval = *nptr - 'a' + 10;
+ else if (*nptr >= 'A' && *nptr <= 'F')
+ digval = *nptr - 'A' + 10;
+ else
+ break;
+ }
+ else
+ break;
+
+ if (result > ULONG_MAX / base
+ || (result == ULONG_MAX / base && digval > ULONG_MAX % base))
{
errno = ERANGE;
if (endptr != NULL)
@@ -297,12 +315,10 @@ _itoa (value, buflim, base, upper_case)
unsigned int base;
int upper_case;
{
- extern const char INTUSE(_itoa_lower_digits)[] attribute_hidden;
-
assert (! upper_case);
do
- *--buflim = INTUSE(_itoa_lower_digits)[value % base];
+ *--buflim = _itoa_lower_digits[value % base];
while ((value /= base) != 0);
return buflim;
@@ -362,5 +378,5 @@ 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. */
-const char INTUSE(_itoa_lower_digits)[16] attribute_hidden
- = "0123456789abcdef";
+const char _itoa_lower_digits[16] = "0123456789abcdef";
+rtld_hidden_data_def (_itoa_lower_digits)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 570c5f8791..9fe0a7ff6a 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -1,5 +1,5 @@
/* Load a shared object at runtime, relocate it, and run its initializer.
- Copyright (C) 1996-2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1996-2007, 2009-2012 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
@@ -325,7 +325,7 @@ dl_open_worker (void *a)
while (l != NULL);
if (nmaps > 1)
{
- char seen[nmaps];
+ uint16_t seen[nmaps];
memset (seen, '\0', nmaps);
size_t i = 0;
while (1)
@@ -351,13 +351,13 @@ dl_open_worker (void *a)
(k - i) * sizeof (maps[0]));
maps[k] = thisp;
- if (seen[i + 1] > 1)
+ if (seen[i + 1] > nmaps - i)
{
++i;
goto next_clear;
}
- char this_seen = seen[i];
+ uint16_t this_seen = seen[i];
memmove (&seen[i], &seen[i + 1],
(k - i) * sizeof (seen[0]));
seen[k] = this_seen;
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 97d2f6f779..e6968a4456 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -1,5 +1,5 @@
/* Relocate a shared object and resolve its references to other loaded objects.
- Copyright (C) 1995-2006, 2008-2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 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,6 +24,7 @@
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/types.h>
+#include <_itoa.h>
#include "dynamic-link.h"
/* Statistics function. */
@@ -338,8 +339,7 @@ void
internal_function __attribute_noinline__
_dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt)
{
- extern const char INTUSE(_itoa_lower_digits)[] attribute_hidden;
-#define DIGIT(b) INTUSE(_itoa_lower_digits)[(b) & 0xf];
+#define DIGIT(b) _itoa_lower_digits[(b) & 0xf];
/* XXX We cannot translate these messages. */
static const char msg[2][32
diff --git a/elf/dl-support.c b/elf/dl-support.c
index e7008078f5..644f3d4622 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -1,5 +1,5 @@
/* Support for dynamic linking code in static libc.
- Copyright (C) 1996-2008,2009,2010,2011 Free Software Foundation, Inc.
+ Copyright (C) 1996-2012 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
@@ -107,6 +107,8 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
size_t _dl_pagesize = /* EXEC_PAGESIZE */ 4096;
+int _dl_inhibit_cache;
+
unsigned int _dl_osversion;
/* All known directories in sorted order. */
@@ -123,6 +125,7 @@ int _dl_debug_fd = STDERR_FILENO;
int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
+ElfW(auxv_t) *_dl_auxv;
ElfW(Phdr) *_dl_phdr;
size_t _dl_phnum;
uint64_t _dl_hwcap __attribute__ ((nocommon));
@@ -185,6 +188,7 @@ _dl_aux_init (ElfW(auxv_t) *av)
uid_t uid = 0;
gid_t gid = 0;
+ _dl_auxv = av;
for (; av->a_type != AT_NULL; ++av)
switch (av->a_type)
{
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 1cb4460a02..e2a9d935ab 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -1,5 +1,5 @@
/* Operating system support for run-time dynamic linker. Generic Unix version.
- Copyright (C) 1995-1998,2000-2008,2009,2010
+ Copyright (C) 1995-1998,2000-2010,2012
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -61,7 +61,6 @@ int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion
/* This variable contains the lowest stack address ever used. */
void *__libc_stack_end attribute_relro = NULL;
rtld_hidden_data_def(__libc_stack_end)
-static ElfW(auxv_t) *_dl_auxv attribute_relro;
void *_dl_random attribute_relro = NULL;
#ifndef DL_FIND_ARG_COMPONENTS
@@ -111,12 +110,12 @@ _dl_sysdep_start (void **start_argptr,
__libc_stack_end = DL_STACK_END (start_argptr);
DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, INTUSE(_dl_argv), _environ,
- _dl_auxv);
+ GLRO(dl_auxv));
user_entry = (ElfW(Addr)) ENTRY_POINT;
GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */
- for (av = _dl_auxv; av->a_type != AT_NULL; set_seen (av++))
+ for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
switch (av->a_type)
{
case AT_PHDR:
@@ -240,7 +239,7 @@ _dl_sysdep_start (void **start_argptr,
if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
__libc_check_standard_fds ();
- (*dl_main) (phdr, phnum, &user_entry, _dl_auxv);
+ (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv));
return user_entry;
}
@@ -265,7 +264,7 @@ _dl_show_auxv (void)
close by (otherwise the array will be too large). In case we have
to support a platform where these requirements are not fulfilled
some alternative implementation has to be used. */
- for (av = _dl_auxv; av->a_type != AT_NULL; ++av)
+ for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
{
static const struct
{
@@ -303,7 +302,9 @@ _dl_show_auxv (void)
};
unsigned int idx = (unsigned int) (av->a_type - 2);
- if ((unsigned int) av->a_type < 2u || auxvars[idx].form == ignore)
+ if ((unsigned int) av->a_type < 2u
+ || (idx < sizeof (auxvars) / sizeof (auxvars[0])
+ && auxvars[idx].form == ignore))
continue;
assert (AT_NULL == 0);
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index aa7122738b..44f53b3c70 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -251,53 +251,13 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
/* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its
range. Note that according to the ELF spec, this is completely legal!
- But conditionally define things so that on machines we know this will
- not happen we do something more optimal. */
-# ifdef ELF_MACHINE_PLTREL_OVERLAP
-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
- do { \
- struct { ElfW(Addr) start, size; \
- __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
- ranges[3]; \
- int ranges_index; \
- \
- ranges[0].lazy = ranges[2].lazy = 0; \
- ranges[1].lazy = 1; \
- ranges[0].size = ranges[1].size = ranges[2].size = 0; \
- ranges[0].nrelative = ranges[1].nrelative = ranges[2].nrelative = 0; \
- \
- if ((map)->l_info[DT_##RELOC]) \
- { \
- ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
- ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
- if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \
- ranges[0].nrelative \
- = MIN (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val, \
- ranges[0].size / sizeof (ElfW(reloc))); \
- } \
- \
- if ((do_lazy) \
- && (map)->l_info[DT_PLTREL] \
- && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
- { \
- ranges[1].start = D_PTR ((map), l_info[DT_JMPREL]); \
- ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
- ranges[2].start = ranges[1].start + ranges[1].size; \
- ranges[2].size = ranges[0].start + ranges[0].size - ranges[2].start; \
- ranges[0].size = ranges[1].start - ranges[0].start; \
- } \
- \
- for (ranges_index = 0; ranges_index < 3; ++ranges_index) \
- elf_dynamic_do_##reloc ((map), \
- ranges[ranges_index].start, \
- ranges[ranges_index].size, \
- ranges[ranges_index].nrelative, \
- ranges[ranges_index].lazy, \
- skip_ifunc); \
- } while (0)
-# else
-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
+ We are guarenteed that we have one of three situations. Either DT_JMPREL
+ comes immediately after DT_REL*, or there is overlap and DT_JMPREL
+ consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
+ are completely separate and there is a gap between them. */
+
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
@@ -316,24 +276,20 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
{ \
ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \
+ ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
\
- if (! ELF_DURING_STARTUP \
- && ((do_lazy) \
- /* This test does not only detect whether the relocation \
- sections are in the right order, it also checks whether \
- there is a DT_REL/DT_RELA section. */ \
- || __builtin_expect (ranges[0].start + ranges[0].size \
- != start, 0))) \
+ if (ranges[0].start + ranges[0].size == (start + size)) \
+ ranges[0].size -= size; \
+ if (! ELF_DURING_STARTUP && ((do_lazy) || ranges[0].size == 0)) \
{ \
ranges[1].start = start; \
- ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
+ ranges[1].size = size; \
ranges[1].lazy = (do_lazy); \
} \
else \
{ \
/* Combine processing the sections. */ \
- assert (ranges[0].start + ranges[0].size == start); \
- ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
+ ranges[0].size += size; \
} \
} \
\
@@ -352,7 +308,6 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
skip_ifunc); \
} \
} while (0)
-# endif
# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
# define _ELF_CHECK_REL 0
diff --git a/elf/elf.h b/elf/elf.h
index a71de7286b..6522ea6b6f 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1327,6 +1327,7 @@ typedef struct
#define R_SPARC_H34 85
#define R_SPARC_SIZE32 86
#define R_SPARC_SIZE64 87
+#define R_SPARC_WDISP10 88
#define R_SPARC_JMP_IREL 248
#define R_SPARC_IRELATIVE 249
#define R_SPARC_GNU_VTINHERIT 250
@@ -2702,8 +2703,9 @@ typedef Elf32_Addr Elf32_Conflict;
descriptor. */
#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
-#define R_X86_64_NUM 38
+#define R_X86_64_NUM 39
/* AM33 relocations. */
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index aa97213cc2..8d6e77f8ec 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2011, 2012 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 1999.
@@ -1061,7 +1061,9 @@ parse_conf (const char *filename, bool do_chroot)
if (file == NULL)
{
- error (0, errno, _("Can't open configuration file %s"), canon);
+ error (0, errno, _("\
+Warning: ignoring configuration file that cannot be opened: %s"),
+ canon);
if (canon != filename)
free ((char *) canon);
return;
diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c
index 6a9edcbd4a..cf49c57b13 100644
--- a/elf/pldd-xx.c
+++ b/elf/pldd-xx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
@@ -23,7 +23,7 @@
#define EW_(e, w, t) EW__(e, w, _##t)
#define EW__(e, w, t) e##w##t
-#define static_assert(name, exp) \
+#define pldd_assert(name, exp) \
typedef int __assert_##name[((exp) != 0) - 1]
@@ -39,11 +39,11 @@ struct E(link_map)
EW(Addr) l_libname;
};
#if CLASS == __ELF_NATIVE_CLASS
-static_assert (l_addr, (offsetof (struct link_map, l_addr)
+pldd_assert (l_addr, (offsetof (struct link_map, l_addr)
== offsetof (struct E(link_map), l_addr)));
-static_assert (l_name, (offsetof (struct link_map, l_name)
+pldd_assert (l_name, (offsetof (struct link_map, l_name)
== offsetof (struct E(link_map), l_name)));
-static_assert (l_next, (offsetof (struct link_map, l_next)
+pldd_assert (l_next, (offsetof (struct link_map, l_next)
== offsetof (struct E(link_map), l_next)));
#endif
@@ -54,9 +54,9 @@ struct E(libname_list)
EW(Addr) next;
};
#if CLASS == __ELF_NATIVE_CLASS
-static_assert (name, (offsetof (struct libname_list, name)
+pldd_assert (name, (offsetof (struct libname_list, name)
== offsetof (struct E(libname_list), name)));
-static_assert (next, (offsetof (struct libname_list, next)
+pldd_assert (next, (offsetof (struct libname_list, next)
== offsetof (struct E(libname_list), next)));
#endif
@@ -69,9 +69,9 @@ struct E(r_debug)
EW(Addr) r_map;
};
#if CLASS == __ELF_NATIVE_CLASS
-static_assert (r_version, (offsetof (struct r_debug, r_version)
+pldd_assert (r_version, (offsetof (struct r_debug, r_version)
== offsetof (struct E(r_debug), r_version)));
-static_assert (r_map, (offsetof (struct r_debug, r_map)
+pldd_assert (r_map, (offsetof (struct r_debug, r_map)
== offsetof (struct E(r_debug), r_map)));
#endif
diff --git a/elf/rtld-Rules b/elf/rtld-Rules
index 6526aec19a..1e03332ca1 100644
--- a/elf/rtld-Rules
+++ b/elf/rtld-Rules
@@ -1,7 +1,6 @@
# Subroutine makefile for compiling libc modules linked into dynamic linker.
-# Copyright (C) 2002,2003,2005,2006,2008,2010,2011
-# Free Software Foundation, Inc.
+# Copyright (C) 2002-2012 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
@@ -130,6 +129,6 @@ ifdef rtld-depfiles
endif
# This here is the whole point of all the shenanigans.
-rtld-CPPFLAGS := -DNOT_IN_libc=1 -DIS_IN_rtld=1
+rtld-CPPFLAGS := -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld
endif
diff --git a/elf/rtld.c b/elf/rtld.c
index 800f172848..00496a7fda 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -161,6 +161,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
._dl_fpu_control = _FPU_DEFAULT,
._dl_pointer_guard = 1,
._dl_pagesize = /* EXEC_PAGESIZE */ 4096,
+ ._dl_inhibit_cache = 0,
/* Function pointers. */
._dl_debug_printf = _dl_debug_printf,
@@ -973,6 +974,13 @@ dl_main (const ElfW(Phdr) *phdr,
--_dl_argc;
++INTUSE(_dl_argv);
}
+ else if (! strcmp (INTUSE(_dl_argv)[1], "--inhibit-cache"))
+ {
+ GLRO(dl_inhibit_cache) = 1;
+ ++_dl_skip_args;
+ --_dl_argc;
+ ++INTUSE(_dl_argv);
+ }
else if (! strcmp (INTUSE(_dl_argv)[1], "--library-path")
&& _dl_argc > 2)
{
@@ -1022,6 +1030,7 @@ of this helper program; chances are you did not intend to run this program.\n\
--list list all dependencies and how they are resolved\n\
--verify verify that given object really is a dynamically linked\n\
object we can handle\n\
+ --inhibit-cache Do not use " LD_SO_CACHE "\n\
--library-path PATH use given PATH instead of content of the environment\n\
variable LD_LIBRARY_PATH\n\
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
@@ -1423,7 +1432,7 @@ of this helper program; chances are you did not intend to run this program.\n\
#endif
#ifdef DL_SYSDEP_OSCHECK
- DL_SYSDEP_OSCHECK (dl_fatal);
+ DL_SYSDEP_OSCHECK (_dl_fatal_printf);
#endif
/* Initialize the data structures for the search paths for shared
@@ -1967,7 +1976,12 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
if (dyn->d_tag == DT_NEEDED)
{
l = l->l_next;
-
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ /* Skip the VDSO since it's not part of the list
+ of objects we brought in via DT_NEEDED entries. */
+ if (l == GLRO(dl_sysinfo_map))
+ l = l->l_next;
+#endif
if (!l->l_used)
{
if (first)
@@ -2278,6 +2292,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
lnp->dont_free = 1;
lnp = lnp->next;
}
+ /* Also allocated with the fake malloc(). */
+ l->l_free_initfini = 0;
if (l != &GL(dl_rtld_map))
_dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
@@ -2500,6 +2516,14 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
++dl_debug;
}
+ if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
+ {
+ /* In order to get an accurate picture of whether a particular
+ DT_NEEDED entry is actually used we have to process both
+ the PLT and non-PLT relocation entries. */
+ GLRO(dl_lazy) = 0;
+ }
+
if (GLRO(dl_debug_mask) & DL_DEBUG_HELP)
{
size_t cnt;
diff --git a/elf/stackguard-macros.h b/elf/stackguard-macros.h
deleted file mode 100644
index a9889cf7b2..0000000000
--- a/elf/stackguard-macros.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdint.h>
-
-#ifdef __i386__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("movl %%gs:0x14, %0" : "=r" (x)); x; })
-#elif defined __x86_64__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("movq %%fs:0x28, %0" : "=r" (x)); x; })
-#elif defined __powerpc64__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; })
-#elif defined __powerpc__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; })
-#elif defined __sparc__ && defined __arch64__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("ldx [%%g7+0x28], %0" : "=r" (x)); x; })
-#elif defined __sparc__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; })
-#elif defined __s390x__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; })
-#elif defined __s390__
-# define STACK_CHK_GUARD \
- ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; })
-#elif !defined STACK_CHK_GUARD
-extern uintptr_t __stack_chk_guard;
-# define STACK_CHK_GUARD __stack_chk_guard
-#endif
diff --git a/elf/tls-macros.h b/elf/tls-macros.h
index ea6f14f56b..e753d5ccaf 100644
--- a/elf/tls-macros.h
+++ b/elf/tls-macros.h
@@ -101,15 +101,15 @@
# define TLS_LE(x) \
({ int *__l; \
- asm ("movq %%fs:0,%0\n\t" \
- "leaq " #x "@tpoff(%0), %0" \
+ asm ("mov %%fs:0,%0\n\t" \
+ "lea " #x "@tpoff(%0), %0" \
: "=r" (__l)); \
__l; })
# define TLS_IE(x) \
({ int *__l; \
- asm ("movq %%fs:0,%0\n\t" \
- "addq " #x "@gottpoff(%%rip),%0" \
+ asm ("mov %%fs:0,%0\n\t" \
+ "add " #x "@gottpoff(%%rip),%0" \
: "=r" (__l)); \
__l; })
@@ -122,9 +122,15 @@
: : "rdi", "rsi", "r8", "r9", "r10", "r11"); \
__l; })
+# ifdef __ILP32__
+# define TLS_GD_PREFIX
+# else
+# define TLS_GD_PREFIX ".byte 0x66\n\t"
+# endif
+
# define TLS_GD(x) \
({ int *__l, __c, __d; \
- asm (".byte 0x66\n\t" \
+ asm (TLS_GD_PREFIX \
"leaq " #x "@tlsgd(%%rip),%%rdi\n\t" \
".word 0x6666\n\t" \
"rex64\n\t" \
diff --git a/elf/tst-auditmod1.c b/elf/tst-auditmod1.c
index 67fc758ac3..108d6ded59 100644
--- a/elf/tst-auditmod1.c
+++ b/elf/tst-auditmod1.c
@@ -109,7 +109,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
# define La_retval La_i86_retval
# define int_retval lrv_eax
#elif defined __x86_64__
-# ifdef __LP64__
+# ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-auditmod3b.c b/elf/tst-auditmod3b.c
index 921eaca55a..a9bb0e22c3 100644
--- a/elf/tst-auditmod3b.c
+++ b/elf/tst-auditmod3b.c
@@ -105,7 +105,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
return sym->st_value;
}
-#ifdef __LP64__
+# ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-auditmod4b.c b/elf/tst-auditmod4b.c
index 75e85582bd..7778d6a172 100644
--- a/elf/tst-auditmod4b.c
+++ b/elf/tst-auditmod4b.c
@@ -94,7 +94,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
return sym->st_value;
}
-#ifdef __LP64__
+# ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-auditmod5b.c b/elf/tst-auditmod5b.c
index d2443c8d20..3a4221536c 100644
--- a/elf/tst-auditmod5b.c
+++ b/elf/tst-auditmod5b.c
@@ -95,7 +95,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
return sym->st_value;
}
-#ifdef __LP64__
+# ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-auditmod6b.c b/elf/tst-auditmod6b.c
index b00dcd7c2e..a9fe5dcadc 100644
--- a/elf/tst-auditmod6b.c
+++ b/elf/tst-auditmod6b.c
@@ -94,7 +94,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
return sym->st_value;
}
-#ifdef __LP64__
+# ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-auditmod6c.c b/elf/tst-auditmod6c.c
index a78c913963..9b1063b23f 100644
--- a/elf/tst-auditmod6c.c
+++ b/elf/tst-auditmod6c.c
@@ -94,7 +94,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
return sym->st_value;
}
-#ifdef __LP64__
+# ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-auditmod7b.c b/elf/tst-auditmod7b.c
index d761149a2f..1ae9e72769 100644
--- a/elf/tst-auditmod7b.c
+++ b/elf/tst-auditmod7b.c
@@ -94,7 +94,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
return sym->st_value;
}
-#ifdef __LP64__
+#ifndef __ILP32__
# define pltenter la_x86_64_gnu_pltenter
# define pltexit la_x86_64_gnu_pltexit
# define La_regs La_x86_64_regs
diff --git a/elf/tst-execstack.c b/elf/tst-execstack.c
index 6632e53367..02cc270d80 100644
--- a/elf/tst-execstack.c
+++ b/elf/tst-execstack.c
@@ -7,6 +7,7 @@
#include <string.h>
#include <unistd.h>
#include <error.h>
+#include <stackinfo.h>
static void
print_maps (void)
@@ -46,7 +47,6 @@ waiter_thread (void *arg)
}
#endif
-
static bool allow_execstack = true;
@@ -107,6 +107,35 @@ do_test (void)
print_maps ();
+#if USE_PTHREADS
+ void *old_stack_addr, *new_stack_addr;
+ size_t stack_size;
+ pthread_t me = pthread_self ();
+ pthread_attr_t attr;
+ int ret = 0;
+
+ ret = pthread_getattr_np (me, &attr);
+ if (ret)
+ {
+ printf ("before execstack: pthread_getattr_np returned error: %s\n",
+ strerror (ret));
+ return 1;
+ }
+
+ ret = pthread_attr_getstack (&attr, &old_stack_addr, &stack_size);
+ if (ret)
+ {
+ printf ("before execstack: pthread_attr_getstack returned error: %s\n",
+ strerror (ret));
+ return 1;
+ }
+# if _STACK_GROWS_DOWN
+ old_stack_addr += stack_size;
+# else
+ old_stack_addr -= stack_size;
+# endif
+#endif
+
/* Loading this module should force stacks to become executable. */
void *h = dlopen ("tst-execstack-mod.so", RTLD_LAZY);
if (h == NULL)
@@ -129,6 +158,46 @@ do_test (void)
print_maps ();
+#if USE_PTHREADS
+ ret = pthread_getattr_np (me, &attr);
+ if (ret)
+ {
+ printf ("after execstack: pthread_getattr_np returned error: %s\n",
+ strerror (ret));
+ return 1;
+ }
+
+ ret = pthread_attr_getstack (&attr, &new_stack_addr, &stack_size);
+ if (ret)
+ {
+ printf ("after execstack: pthread_attr_getstack returned error: %s\n",
+ strerror (ret));
+ return 1;
+ }
+
+# if _STACK_GROWS_DOWN
+ new_stack_addr += stack_size;
+# else
+ new_stack_addr -= stack_size;
+# endif
+
+ /* It is possible that the dlopen'd module may have been mmapped just below
+ the stack. The stack size is taken as MIN(stack rlimit size, end of last
+ vma) in pthread_getattr_np. If rlimit is set high enough, it is possible
+ that the size may have changed. A subsequent call to
+ pthread_attr_getstack returns the size and (bottom - size) as the
+ stacksize and stackaddr respectively. If the size changes due to the
+ above, then both stacksize and stackaddr can change, but the stack bottom
+ should remain the same, which is computed as stackaddr + stacksize. */
+ if (old_stack_addr != new_stack_addr)
+ {
+ printf ("Stack end changed, old: %p, new: %p\n",
+ old_stack_addr, new_stack_addr);
+ return 1;
+ }
+ printf ("Stack address remains the same: %p\n", old_stack_addr);
+#endif
+
/* Test that growing the stack region gets new executable pages too. */
deeper ((void (*) (void)) f);
diff --git a/elf/tst-relsort1.c b/elf/tst-relsort1.c
index 972100c0e9..a87b138280 100644
--- a/elf/tst-relsort1.c
+++ b/elf/tst-relsort1.c
@@ -3,7 +3,7 @@
static int
-do_test ()
+do_test (void)
{
const char lib[] = "$ORIGIN/tst-relsort1mod1.so";
void *h = dlopen (lib, RTLD_NOW);