summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-05-28 05:06:27 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-05-28 05:06:53 -0700
commit58007e9e68913290b1f4f73afc1055f779a8ed5d (patch)
tree6a76be39e885bdcd159ba571f25b9eea83f709c0
parentbe2e25bbd78f9fdf27bed254d02915d019c5b363 (diff)
Make sure that calloc is called at least once
PLT relocations aren't required when -z now used. Linker on master with: commit 25070364b0ce33eed46aa5d78ebebbec6accec7e Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat May 16 07:00:21 2015 -0700 Don't generate PLT relocations for now binding There is no need for PLT relocations with -z now. We can use GOT relocations, which take less space, instead and replace 16-byte .plt entres with 8-byte .plt.got entries. bfd/ * elf32-i386.c (elf_i386_check_relocs): Create .plt.got section for now binding. (elf_i386_allocate_dynrelocs): Use .plt.got section for now binding. * elf64-x86-64.c (elf_x86_64_check_relocs): Create .plt.got section for now binding. (elf_x86_64_allocate_dynrelocs): Use .plt.got section for now binding. won't generate PLT relocations with -z now. elf/tst-audit2.c expect certain order of execution in ld.so.  With PLT relocations, the GOTPLT entry of calloc is update to calloc defined in tst-audit2: (gdb) bt     skip_ifunc=<optimized out>, reloc_addr_arg=<optimized out>,     version=<optimized out>, sym=<optimized out>, map=<optimized out>)     at ../sysdeps/i386/dl-machine.h:329 out>,     nrelative=<optimized out>, relsize=<optimized out>,     reladdr=<optimized out>, map=<optimized out>) at do-rel.h:137 reloc_mode=reloc_mode@entry=0,     consider_profiling=1, consider_profiling@entry=0) at dl-reloc.c:258     user_entry=0xffffcf1c, auxv=0xffffd0a8) at rtld.c:2133     start_argptr=start_argptr@entry=0xffffcfb0,     dl_main=dl_main@entry=0xf7fda6f0 <dl_main>) at ../elf/dl-sysdep.c:249    from /export/build/gnu/glibc-32bit/build-i686-linux/elf/ld.so (gdb) and then calloc is called: (gdb) c Continuing. Breakpoint 4, calloc (n=n@entry=20, m=4) at tst-audit2.c:18 18 { (gdb) bt     reloc_mode=reloc_mode@entry=0, consider_profiling=1,     consider_profiling@entry=0) at dl-reloc.c:272     user_entry=0xffffcf1c, auxv=0xffffd0a8) at rtld.c:2133     start_argptr=start_argptr@entry=0xffffcfb0,     dl_main=dl_main@entry=0xf7fda6f0 <dl_main>) at ../elf/dl-sysdep.c:249    from /export/build/gnu/glibc-32bit/build-i686-linux/elf/ld.so (gdb) With GOT relocation, calloc in ld.so is called first: (gdb) bt     consider_profiling=1) at dl-reloc.c:272     user_entry=0xffffcf0c, auxv=0xffffd098) at rtld.c:2074     start_argptr=start_argptr@entry=0xffffcfa0,     dl_main=dl_main@entry=0xf7fda6c0 <dl_main>) at ../elf/dl-sysdep.c:249    from /export/build/gnu/glibc-32bit-test/build-i686-linux/elf/ld.so (gdb) and then the GOT entry of calloc is updated: (gdb) bt     skip_ifunc=<optimized out>, reloc_addr_arg=<optimized out>,     version=<optimized out>, sym=<optimized out>, map=<optimized out>)     at ../sysdeps/i386/dl-machine.h:329 out>,     nrelative=<optimized out>, relsize=<optimized out>,     reladdr=<optimized out>, map=<optimized out>) at do-rel.h:137 reloc_mode=reloc_mode@entry=0,     consider_profiling=1, consider_profiling@entry=0) at dl-reloc.c:258     user_entry=0xffffcf0c, auxv=0xffffd098) at rtld.c:2133     start_argptr=start_argptr@entry=0xffffcfa0,     dl_main=dl_main@entry=0xf7fda6c0 <dl_main>) at ../elf/dl-sysdep.c:249    from /export/build/gnu/glibc-32bit-test/build-i686-linux/elf/ld.so (gdb) After that, since calloc isn't called from ld.so nor any other modules, magic in tst-audit2 isn't updated.  Both orders are correct. This patch makes sure that calloc in tst-audit2.c is called at least once from ld.so. [BZ #18422] * Makefile ($(objpfx)tst-audit2): Depend on $(libdl). ($(objpfx)tst-audit2.out): Also depend on $(objpfx)tst-auditmod9b.so. * elf/tst-audit2.c: Include <dlfcn.h>. (calloc_called): New. (calloc): Allow to be called more than once. (do_test): dllopen/dlclose $ORIGIN/tst-auditmod9b.so.
-rw-r--r--ChangeLog11
-rw-r--r--NEWS2
-rw-r--r--elf/Makefile3
-rw-r--r--elf/tst-audit2.c26
4 files changed, 34 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index e3a6bacb1a..b68eab55c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2015-05-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #18422]
+ * Makefile ($(objpfx)tst-audit2): Depend on $(libdl).
+ ($(objpfx)tst-audit2.out): Also depend on
+ $(objpfx)tst-auditmod9b.so.
+ * elf/tst-audit2.c: Include <dlfcn.h>.
+ (calloc_called): New.
+ (calloc): Allow to be called more than once.
+ (do_test): dllopen/dlclose $ORIGIN/tst-auditmod9b.so.
+
2015-05-28 Wilco Dijkstra <wdijkstr@arm.com>
* sysdeps/ieee754/dbl-64/s_fabs.c: (__fabs): Call __builtin_fabs.
diff --git a/NEWS b/NEWS
index 4aff69d3e5..8e2976e366 100644
--- a/NEWS
+++ b/NEWS
@@ -19,7 +19,7 @@ Version 2.22
18047, 18049, 18068, 18080, 18093, 18100, 18104, 18110, 18111, 18125,
18128, 18138, 18185, 18196, 18197, 18206, 18210, 18211, 18217, 18220,
18221, 18234, 18244, 18247, 18287, 18319, 18333, 18346, 18397, 18409,
- 18410, 18412, 18418, 18434, 18444.
+ 18410, 18412, 18418, 18422, 18434, 18444.
* Cache information can be queried via sysconf() function on s390 e.g. with
_SC_LEVEL1_ICACHE_SIZE as argument.
diff --git a/elf/Makefile b/elf/Makefile
index b06e0a7ed2..dedf3c7f50 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1034,7 +1034,8 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
$(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so
tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
-$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so
+$(objpfx)tst-audit2: $(libdl)
+$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so $(objpfx)tst-auditmod9b.so
# Prevent GCC-5 from translating a malloc/memset pair into calloc
CFLAGS-tst-audit2.c += -fno-builtin
tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c
index acad1b05cf..1d69cd669e 100644
--- a/elf/tst-audit2.c
+++ b/elf/tst-audit2.c
@@ -3,26 +3,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <dlfcn.h>
#define MAGIC1 0xabcdef72
#define MAGIC2 0xd8675309
static __thread unsigned int magic[] = { MAGIC1, MAGIC2 };
+static __thread int calloc_called;
#undef calloc
/* This calloc definition will be called by the dynamic linker itself.
- We test that it has initialized our TLS block by the time it does so. */
+ We test that interposed calloc is called by the dynamic loader, and
+ that TLS is fully initialized by then. */
void *
calloc (size_t n, size_t m)
{
- if (magic[0] != MAGIC1 || magic[1] != MAGIC2)
+ if (!calloc_called)
{
- printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC1, MAGIC2);
- abort ();
+ /* Allow our calloc to be called more than once. */
+ calloc_called = 1;
+ if (magic[0] != MAGIC1 || magic[1] != MAGIC2)
+ {
+ printf ("{%x, %x} != {%x, %x}\n",
+ magic[0], magic[1], MAGIC1, MAGIC2);
+ abort ();
+ }
+ magic[0] = MAGIC2;
+ magic[1] = MAGIC1;
}
- magic[0] = MAGIC2;
- magic[1] = MAGIC1;
n *= m;
void *ptr = malloc (n);
@@ -34,6 +43,11 @@ calloc (size_t n, size_t m)
static int
do_test (void)
{
+ /* Make sure that our calloc is called from the dynamic linker at least
+ once. */
+ void *h = dlopen("$ORIGIN/tst-auditmod9b.so", RTLD_LAZY);
+ if (h != NULL)
+ dlclose (h);
if (magic[1] != MAGIC1 || magic[0] != MAGIC2)
{
printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1);