Fix dynamic linker issue with bind-now

Fix the bind-now case when DT_REL and DT_JMPREL sections are separate
and there is a gap between them.

	[BZ #14341]
	* elf/dynamic-link.h (elf_machine_lazy_rel): Properly handle the
	case when there is a gap between DT_REL and DT_JMPREL sections.
	* sysdeps/x86_64/Makefile (tests): Add tst-split-dynreloc.
	(LDFLAGS-tst-split-dynreloc): New.
	(tst-split-dynreloc-ENV): Likewise.
	* sysdeps/x86_64/tst-split-dynreloc.c: New file.
	* sysdeps/x86_64/tst-split-dynreloc.lds: Likewise.
This commit is contained in:
Petar Jovanovic 2014-08-20 00:50:54 +02:00 committed by H.J. Lu
parent 33c898d160
commit fa19d5c48a
5 changed files with 57 additions and 6 deletions

View File

@ -1,3 +1,14 @@
2015-08-19 Petar Jovanovic <petar.jovanovic@rt-rk.com>
[BZ #14341]
* elf/dynamic-link.h (elf_machine_lazy_rel): Properly handle the
case when there is a gap between DT_REL and DT_JMPREL sections.
* sysdeps/x86_64/Makefile (tests): Add tst-split-dynreloc.
(LDFLAGS-tst-split-dynreloc): New.
(tst-split-dynreloc-ENV): Likewise.
* sysdeps/x86_64/tst-split-dynreloc.c: New file.
* sysdeps/x86_64/tst-split-dynreloc.lds: Likewise.
2015-08-19 H.J. Lu <hongjiu.lu@intel.com>
[BZ #18822]

View File

@ -135,17 +135,19 @@ elf_machine_lazy_rel (struct link_map *map,
\
if (ranges[0].start + ranges[0].size == (start + size)) \
ranges[0].size -= size; \
if (! ELF_DURING_STARTUP && ((do_lazy) || ranges[0].size == 0)) \
if (ELF_DURING_STARTUP \
|| (!(do_lazy) \
&& (ranges[0].start + ranges[0].size) == start)) \
{ \
/* Combine processing the sections. */ \
ranges[0].size += size; \
} \
else \
{ \
ranges[1].start = start; \
ranges[1].size = size; \
ranges[1].lazy = (do_lazy); \
} \
else \
{ \
/* Combine processing the sections. */ \
ranges[0].size += size; \
} \
} \
\
if (ELF_DURING_STARTUP) \

View File

@ -38,6 +38,11 @@ tests += tst-audit3 tst-audit4 tst-audit5 tst-audit10
ifeq (yes,$(config-cflags-avx))
tests += tst-audit6 tst-audit7
endif
tests += tst-split-dynreloc
LDFLAGS-tst-split-dynreloc = -Wl,-T,$(..)sysdeps/x86_64/tst-split-dynreloc.lds
tst-split-dynreloc-ENV = LD_BIND_NOW=1
modules-names += tst-auditmod3a tst-auditmod3b \
tst-auditmod4a tst-auditmod4b \
tst-auditmod5a tst-auditmod5b \

View File

@ -0,0 +1,28 @@
/* This test will be used to create an executable with a specific
section layout in which .rela.dyn and .rela.plt are not contiguous.
For x86 case, readelf will report something like:
...
[10] .rela.dyn RELA
[11] .bar PROGBITS
[12] .rela.plt RELA
...
This is important as this case was not correctly handled by dynamic
linker in the bind-now case, and the second section was never
processed. */
#include <stdio.h>
const int __attribute__ ((section(".bar"))) bar = 0x12345678;
static const char foo[] = "foo";
static int
do_test (void)
{
printf ("%s %d\n", foo, bar);
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -0,0 +1,5 @@
SECTIONS
{
.bar : { *(.bar) }
}
INSERT AFTER .rela.dyn;