mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
58007e9e68
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.
62 lines
1.4 KiB
C
62 lines
1.4 KiB
C
/* Test case for early TLS initialization in dynamic linker. */
|
|
|
|
#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 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 (!calloc_called)
|
|
{
|
|
/* 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;
|
|
}
|
|
|
|
n *= m;
|
|
void *ptr = malloc (n);
|
|
if (ptr != NULL)
|
|
memset (ptr, '\0', n);
|
|
return ptr;
|
|
}
|
|
|
|
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);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define TEST_FUNCTION do_test ()
|
|
#include "../test-skeleton.c"
|