aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/exec.c19
-rw-r--r--testsuite/Makefile.am3
-rw-r--r--testsuite/Makefile.in3
-rwxr-xr-xtestsuite/shuffle6.sh33
-rw-r--r--testsuite/shuffle6lib1.c20
-rw-r--r--testsuite/shuffle6lib2.c16
-rwxr-xr-xtestsuite/shuffle7.sh44
7 files changed, 133 insertions, 5 deletions
diff --git a/src/exec.c b/src/exec.c
index 8e0decb..5543016 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -452,7 +452,7 @@ prelink_exec (struct prelink_info *info)
Elf_Data *data = elf_getdata (dso->scn[i], NULL);
assert (data->d_buf == NULL);
- assert (data->d_size == shdr[i].sh_size);
+ data->d_size = shdr[i].sh_size;
data->d_buf = calloc (shdr[i].sh_size, 1);
if (data->d_buf == NULL)
{
@@ -886,8 +886,21 @@ prelink_exec (struct prelink_info *info)
if (old_dynbss == -1)
{
data = elf_getdata (dso->scn[new_dynbss + 1], NULL);
- assert (dso->shdr[new_dynbss + 1].sh_type != SHT_NOBITS
- || data->d_buf == NULL);
+ if (dso->shdr[new_dynbss + 1].sh_type == SHT_NOBITS
+ && data->d_buf != NULL)
+ {
+#ifndef NDEBUG
+ char *buf_start = data->d_buf;
+ char *buf_end = buf_start + data->d_size;
+
+ while (buf_start < buf_end)
+ if (*buf_start++)
+ break;
+ assert (buf_start == buf_end);
+#endif
+ free (data->d_buf);
+ data->d_buf = NULL;
+ }
if (data->d_size != dso->shdr[new_dynbss + 1].sh_size)
{
assert (data->d_size == dso->shdr[new_dynbss].sh_size
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 34f1e37..3f5754c 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -9,6 +9,7 @@ TESTS = movelibs.sh \
reloc1.sh reloc2.sh reloc3.sh reloc4.sh reloc5.sh reloc6.sh \
reloc7.sh reloc8.sh reloc9.sh reloc10.sh reloc11.sh \
shuffle1.sh shuffle2.sh shuffle3.sh shuffle4.sh shuffle5.sh \
+ shuffle6.sh shuffle7.sh \
layout1.sh layout2.sh tls1.sh tls2.sh tls3.sh tls4.sh \
cxx1.sh quick1.sh cycle1.sh cycle2.sh \
undosyslibs.sh
@@ -22,7 +23,7 @@ extra_DIST = $(TESTS) functions.sh
CLEANFILES = *.so *.so.* *.nop syslib.list syslnk.list prelink.cache prelink.conf \
$(TESTS:%.sh=%) $(TESTS:%.sh=%.log) $(TESTS:%.sh=%.lds) \
- *.orig *.new core* *.\#prelink\#* tlstest
+ *.orig *.new core* *.\#prelink\#* tlstest *.first *.second
clean-am: clean-dirs
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index 658a564..a70ab54 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -97,6 +97,7 @@ TESTS = movelibs.sh \
reloc1.sh reloc2.sh reloc3.sh reloc4.sh reloc5.sh reloc6.sh \
reloc7.sh reloc8.sh reloc9.sh reloc10.sh reloc11.sh \
shuffle1.sh shuffle2.sh shuffle3.sh shuffle4.sh shuffle5.sh \
+ shuffle6.sh shuffle7.sh \
layout1.sh layout2.sh tls1.sh tls2.sh tls3.sh tls4.sh \
cxx1.sh quick1.sh cycle1.sh cycle2.sh \
undosyslibs.sh
@@ -112,7 +113,7 @@ extra_DIST = $(TESTS) functions.sh
CLEANFILES = *.so *.so.* *.nop syslib.list syslnk.list prelink.cache prelink.conf \
$(TESTS:%.sh=%) $(TESTS:%.sh=%.log) $(TESTS:%.sh=%.lds) \
- *.orig *.new core* *.\#prelink\#* tlstest
+ *.orig *.new core* *.\#prelink\#* tlstest *.first *.second
subdir = testsuite
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
diff --git a/testsuite/shuffle6.sh b/testsuite/shuffle6.sh
new file mode 100755
index 0000000..6fa4085
--- /dev/null
+++ b/testsuite/shuffle6.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+. `dirname $0`/functions.sh
+rm -f shuffle6 shuffle6lib*.so shuffle6.log shuffle6.lds
+rm -f prelink.cache
+$CC -shared -O2 -fpic -o shuffle6lib1.so $srcdir/reloc1lib1.c
+$CC -shared -O2 -fpic -o shuffle6lib2.so $srcdir/reloc1lib2.c shuffle6lib1.so
+BINS="shuffle6"
+LIBS="shuffle6lib1.so shuffle6lib2.so"
+$CCLINK -o shuffle6 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle6lib2.so \
+ -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \
+ -e 's/0x08048000/0x08000000/;s/SIZEOF_HEADERS.*$/& . += 56;/' > shuffle6.lds
+$CCLINK -o shuffle6 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle6lib2.so \
+ -Wl,-T,shuffle6.lds
+savelibs
+echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle6 > shuffle6.log
+$PRELINK ${PRELINK_OPTS--vm} ./shuffle6 >> shuffle6.log 2>&1 || exit 1
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle6.log && exit 2
+LD_LIBRARY_PATH=. ./shuffle6 || exit 3
+readelf -a ./shuffle6 >> shuffle6.log 2>&1 || exit 4
+comparelibs >> shuffle6.log 2>&1 || exit 5
+for l in shuffle6lib{1,2}.so{,.orig}; do mv -f $l $l.first; done
+cp -p shuffle6 shuffle6.first
+$CC -shared -O2 -fpic -o shuffle6lib1.so $srcdir/shuffle6lib1.c
+$CC -shared -O2 -fpic -o shuffle6lib2.so $srcdir/shuffle6lib2.c shuffle6lib1.so
+for l in shuffle6lib{1,2}.so; do cp -p $l $l.orig; done
+echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle6 >> shuffle6.log
+$PRELINK ${PRELINK_OPTS--vm} ./shuffle6 >> shuffle6.log 2>&1 || exit 6
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle6.log && exit 7
+LD_LIBRARY_PATH=. ./shuffle6 || exit 8
+readelf -a ./shuffle6 >> shuffle6.log 2>&1 || exit 9
+# So that it is not prelinked again
+chmod -x ./shuffle6
+comparelibs >> shuffle6.log 2>&1 || exit 10
diff --git a/testsuite/shuffle6lib1.c b/testsuite/shuffle6lib1.c
new file mode 100644
index 0000000..8053293
--- /dev/null
+++ b/testsuite/shuffle6lib1.c
@@ -0,0 +1,20 @@
+#include "reloc1.h"
+
+int bar = 26;
+int baz = 28;
+#define M(i) int b##i, *pb##i = &b##i;
+M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9)
+M(10) M(11) M(12) M(13) M(14) M(15) M(16) M(17) M(18) M(19)
+#undef M
+
+struct A foo = { 1, &foo, &bar };
+
+int f1 (void)
+{
+ return 1;
+}
+
+int f2 (void)
+{
+ return f1 () + 1;
+}
diff --git a/testsuite/shuffle6lib2.c b/testsuite/shuffle6lib2.c
new file mode 100644
index 0000000..ed18f6b
--- /dev/null
+++ b/testsuite/shuffle6lib2.c
@@ -0,0 +1,16 @@
+#include "reloc1.h"
+#include <stdlib.h>
+
+#define M(i) int b##i; extern *pb##i;
+M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9)
+M(10) M(11) M(12) M(13) M(14) M(15) M(16) M(17) M(18) M(19)
+#undef M
+
+int f1 (void)
+{
+#define M(i) if (pb##i != &b##i) abort ();
+M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9)
+M(10) M(11) M(12) M(13) M(14) M(15) M(16) M(17) M(18) M(19)
+#undef M
+ return 11;
+}
diff --git a/testsuite/shuffle7.sh b/testsuite/shuffle7.sh
new file mode 100755
index 0000000..f682866
--- /dev/null
+++ b/testsuite/shuffle7.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+. `dirname $0`/functions.sh
+rm -f shuffle7 shuffle7lib*.so shuffle7.log shuffle7.lds
+rm -f prelink.cache
+$CC -shared -O2 -fpic -o shuffle7lib1.so $srcdir/reloc1lib1.c
+$CC -shared -O2 -fpic -o shuffle7lib2.so $srcdir/reloc1lib2.c shuffle7lib1.so
+BINS="shuffle7"
+LIBS="shuffle7lib1.so shuffle7lib2.so"
+$CCLINK -o shuffle7 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle7lib2.so \
+ -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \
+ -e '/\.hash/a\
+ . = . + 0x300;' > shuffle7.lds
+$CCLINK -o shuffle7 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle7lib2.so \
+ -Wl,-T,shuffle7.lds
+savelibs
+echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 > shuffle7.log
+$PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log 2>&1 || exit 1
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle7.log && exit 2
+LD_LIBRARY_PATH=. ./shuffle7 || exit 3
+readelf -a ./shuffle7 >> shuffle7.log 2>&1 || exit 4
+comparelibs >> shuffle7.log 2>&1 || exit 5
+for l in shuffle7lib{1,2}.so{,.orig}; do mv -f $l $l.first; done
+cp -p shuffle7 shuffle7.first
+$CC -shared -O2 -fpic -o shuffle7lib1.so $srcdir/shuffle6lib1.c
+$CC -shared -O2 -fpic -o shuffle7lib2.so $srcdir/shuffle6lib2.c shuffle7lib1.so
+for l in shuffle7lib{1,2}.so; do cp -p $l $l.orig; done
+echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log
+$PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log 2>&1 || exit 6
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle7.log && exit 7
+LD_LIBRARY_PATH=. ./shuffle7 || exit 8
+readelf -a ./shuffle7 >> shuffle7.log 2>&1 || exit 9
+comparelibs >> shuffle7.log 2>&1 || exit 10
+for l in shuffle7lib{1,2}.so{,.orig}; do mv -f $l $l.second; done
+cp -p shuffle7 shuffle7.second
+for l in shuffle7lib{1,2}.so{,.orig}; do cp -p $l.first $l; done
+echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log
+$PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log 2>&1 || exit 11
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle7.log && exit 12
+LD_LIBRARY_PATH=. ./shuffle7 || exit 13
+readelf -a ./shuffle7 >> shuffle7.log 2>&1 || exit 14
+comparelibs >> shuffle7.log 2>&1 || exit 15
+cmp -s shuffle7{,.first} || exit 16
+# So that it is not prelinked again
+chmod -x ./shuffle7