[v3] Fix dynamic linker issue with bind-now

Message ID 1425312822-25143-1-git-send-email-petar.jovanovic@rt-rk.com
State Superseded
Headers

Commit Message

Petar Jovanovic March 2, 2015, 4:13 p.m. UTC
  Fix the bind-now case when DT_REL and DT_JMPREL sections are separate
and there is a gap between them.
---
v3:
- addressed comments raised by Mike Frysinger
  - use of test-skeleton.c
  - use -Wl,-z,now instead of LD_BIND_NOW=1
  - moved comments to the start of the test file

v2:
- addressed code style comments raised by Andreas Schwab

 elf/Makefile               |    5 ++++-
 elf/dynamic-link.h         |    4 +++-
 elf/tst-split-dynreloc.c   |   28 ++++++++++++++++++++++++++++
 elf/tst-split-dynreloc.lds |    6 ++++++
 4 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 elf/tst-split-dynreloc.c
 create mode 100644 elf/tst-split-dynreloc.lds
  

Comments

Mike Frysinger March 2, 2015, 5:39 p.m. UTC | #1
On 02 Mar 2015 17:13, Petar Jovanovic wrote:
> --- /dev/null
> +++ b/elf/tst-split-dynreloc.lds
> @@ -0,0 +1,6 @@
> +SECTIONS
> +{
> +   .bar : { *(.bar) }
> +}
> +INSERT AFTER .rela.dyn;

what about arches that don't use RELA relocations ?  x86 (32-bit) should be such 
a target and easy for you to test.
-mike
  

Patch

diff --git a/elf/Makefile b/elf/Makefile
index 20b1682..8e15602 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -146,8 +146,11 @@  tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	 tst-stackguard1 tst-addr1 tst-thrlock \
 	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
 	 tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
-	 tst-ptrguard1
+	 tst-ptrguard1 tst-split-dynreloc
 #	 reldep9
+
+LDFLAGS-tst-split-dynreloc = -fPIE -Wl,-T,tst-split-dynreloc.lds -Wl,-z,now
+
 ifeq ($(build-hardcoded-path-in-tests),yes)
 tests += tst-dlopen-aout
 endif
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 6f4a773..2536b8d 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -132,7 +132,9 @@  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].size == 0			      \
+		|| ranges[0].start + ranges[0].size != start))		      \
 	  {								      \
 	    ranges[1].start = start;					      \
 	    ranges[1].size = size;					      \
diff --git a/elf/tst-split-dynreloc.c b/elf/tst-split-dynreloc.c
new file mode 100644
index 0000000..bdb6b7c
--- /dev/null
+++ b/elf/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>
+
+static 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/elf/tst-split-dynreloc.lds b/elf/tst-split-dynreloc.lds
new file mode 100644
index 0000000..ed0a656
--- /dev/null
+++ b/elf/tst-split-dynreloc.lds
@@ -0,0 +1,6 @@ 
+SECTIONS
+{
+   .bar : { *(.bar) }
+}
+INSERT AFTER .rela.dyn;
+