]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix dynamic linker issue with bind-now
authorPetar Jovanovic <petar.jovanovic@rt-rk.com>
Tue, 19 Aug 2014 22:50:54 +0000 (00:50 +0200)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 19 Aug 2015 12:37:01 +0000 (05:37 -0700)
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.

ChangeLog
elf/dynamic-link.h
sysdeps/x86_64/Makefile
sysdeps/x86_64/tst-split-dynreloc.c [new file with mode: 0644]
sysdeps/x86_64/tst-split-dynreloc.lds [new file with mode: 0644]

index 83fef46af22ac95fed2b24fe238c0ae91a4dbf4c..4218f2cadd3c36e48df070703c7314660a7e58e8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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]
index 8d428e20d39943cfa1195d06423f0284a6ad190f..d7cff482d4c99701eb7c311bf89aa7f172e9471f 100644 (file)
@@ -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);                                       \
          }                                                                   \
       }                                                                              \
                                                                              \
index ef70a50c843b49a442ae6261a424c71a4bbf53f1..91875f013744d7a4542d6309a8c13ea616187544 100644 (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 \
diff --git a/sysdeps/x86_64/tst-split-dynreloc.c b/sysdeps/x86_64/tst-split-dynreloc.c
new file mode 100644 (file)
index 0000000..2f9e9b9
--- /dev/null
@@ -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 (file)
index 0000000..2229e69
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+   .bar : { *(.bar) }
+}
+INSERT AFTER .rela.dyn;