diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | elf/dynamic-link.h | 14 | ||||
-rw-r--r-- | sysdeps/x86_64/Makefile | 5 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-split-dynreloc.c | 28 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-split-dynreloc.lds | 5 |
5 files changed, 57 insertions, 6 deletions
@@ -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] diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 8d428e20d3..d7cff482d4 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -135,16 +135,18 @@ 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)) \ { \ - ranges[1].start = start; \ - ranges[1].size = size; \ - ranges[1].lazy = (do_lazy); \ + /* Combine processing the sections. */ \ + ranges[0].size += size; \ } \ else \ { \ - /* Combine processing the sections. */ \ - ranges[0].size += size; \ + ranges[1].start = start; \ + ranges[1].size = size; \ + ranges[1].lazy = (do_lazy); \ } \ } \ \ diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile index ef70a50c84..91875f0137 100644 --- a/sysdeps/x86_64/Makefile +++ b/sysdeps/x86_64/Makefile @@ -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 \ diff --git a/sysdeps/x86_64/tst-split-dynreloc.c b/sysdeps/x86_64/tst-split-dynreloc.c new file mode 100644 index 0000000000..2f9e9b9477 --- /dev/null +++ b/sysdeps/x86_64/tst-split-dynreloc.c @@ -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" diff --git a/sysdeps/x86_64/tst-split-dynreloc.lds b/sysdeps/x86_64/tst-split-dynreloc.lds new file mode 100644 index 0000000000..2229e698c9 --- /dev/null +++ b/sysdeps/x86_64/tst-split-dynreloc.lds @@ -0,0 +1,5 @@ +SECTIONS +{ + .bar : { *(.bar) } +} +INSERT AFTER .rela.dyn; |