aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/doit.c4
-rw-r--r--src/dso.c21
-rw-r--r--src/exec.c4
-rw-r--r--src/execstack.c6
-rw-r--r--src/main.c22
-rw-r--r--src/prelink.c8
-rw-r--r--src/prelink.h6
-rw-r--r--src/undo.c6
-rw-r--r--src/undoall.c4
-rw-r--r--testsuite/Makefile.am2
-rw-r--r--testsuite/Makefile.in2
-rwxr-xr-xtestsuite/undo1.sh22
12 files changed, 72 insertions, 35 deletions
diff --git a/src/doit.c b/src/doit.c
index 8c62861..31c32fd 100644
--- a/src/doit.c
+++ b/src/doit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2001, 2003, 2004, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -147,7 +147,7 @@ prelink_ent (struct prelink_entry *ent)
goto make_unprelinkable;
if (prelink (dso, ent))
goto make_unprelinkable;
- if (update_dso (dso))
+ if (update_dso (dso, NULL))
{
dso = NULL;
goto error_out;
diff --git a/src/dso.c b/src/dso.c
index 1706bed..2c9889e 100644
--- a/src/dso.c
+++ b/src/dso.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -724,9 +724,10 @@ remove_section (struct section_move *move, int sec)
}
int
-reopen_dso (DSO *dso, struct section_move *move)
+reopen_dso (DSO *dso, struct section_move *move, const char *temp_base)
{
- char filename[strlen (dso->filename) + sizeof ("/dev/shm/.#prelink#.XXXXXX")];
+ char filename[strlen (temp_base ? temp_base : dso->filename)
+ + sizeof ("/dev/shm/.#prelink#.XXXXXX")];
int adddel = 0;
int free_move = 0;
Elf *elf = NULL;
@@ -742,11 +743,11 @@ reopen_dso (DSO *dso, struct section_move *move)
free_move = 1;
}
else
- {
- assert (dso->ehdr.e_shnum == move->old_shnum);
- }
+ assert (dso->ehdr.e_shnum == move->old_shnum);
- sprintf (filename, "%s.#prelink#.XXXXXX", dso->filename);
+ if (temp_base == NULL)
+ temp_base = dso->filename;
+ sprintf (filename, "%s.#prelink#.XXXXXX", temp_base);
fd = mkstemp (filename);
if (fd == -1)
@@ -1570,7 +1571,7 @@ relocate_dso (DSO *dso, GElf_Addr base)
if (! dso_is_rdwr (dso))
{
- if (reopen_dso (dso, NULL))
+ if (reopen_dso (dso, NULL, NULL))
return 1;
}
@@ -1698,7 +1699,7 @@ set_security_context (DSO *dso, const char *temp_name, const char *name)
}
int
-update_dso (DSO *dso)
+update_dso (DSO *dso, const char *orig_name)
{
int rdwr = dso_is_rdwr (dso);
@@ -1741,7 +1742,7 @@ update_dso (DSO *dso)
u.modtime = st.st_mtime;
utime (name2, &u);
- if (set_security_context (dso, name2, name1))
+ if (set_security_context (dso, name2, orig_name ? orig_name : name1))
{
unlink (name2);
return 1;
diff --git a/src/exec.c b/src/exec.c
index 1dd2fdc..3d8b11a 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -428,7 +428,7 @@ prelink_exec (struct prelink_info *info)
ehdr.e_shnum = dso->ehdr.e_shnum;
dso->ehdr = ehdr;
memcpy (dso->phdr, phdr, ehdr.e_phnum * sizeof (GElf_Phdr));
- if (reopen_dso (dso, move))
+ if (reopen_dso (dso, move, NULL))
goto error_out;
assert (i == dso->ehdr.e_shnum);
diff --git a/src/execstack.c b/src/execstack.c
index 9f8bf7e..1e50aad 100644
--- a/src/execstack.c
+++ b/src/execstack.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Red Hat, Inc.
+/* Copyright (C) 2003, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2003.
This program is free software; you can redistribute it and/or modify
@@ -100,7 +100,7 @@ execstack_make_rdwr (DSO *dso, int flag)
}
if (i == dso->ehdr.e_shnum)
- return reopen_dso (dso, NULL) ? 1 : -1;
+ return reopen_dso (dso, NULL, NULL) ? 1 : -1;
/* We need to unprelink the file first, so that prelink --undo
or reprelinking it doesn't destroy the PT_GNU_STACK segment
@@ -368,7 +368,7 @@ out_write:
dso->permissive = 1;
- return update_dso (dso);
+ return update_dso (dso, NULL);
out_close:
close_dso (dso);
diff --git a/src/main.c b/src/main.c
index 48c9201..cb7e5ad 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -283,7 +283,8 @@ main (int argc, char *argv[])
{
DSO *dso = open_dso (argv[remaining++]);
- if (dso == NULL || reopen_dso (dso, NULL) || prelink_set_checksum (dso))
+ if (dso == NULL || reopen_dso (dso, NULL, NULL)
+ || prelink_set_checksum (dso))
error (0, 0, "could not recompute checksum of %s", dso->filename);
close_dso (dso);
error (0, 0, "%08x %s\n", (unsigned int) dso->info_DT_CHECKSUM, dso->filename);
@@ -351,6 +352,7 @@ main (int argc, char *argv[])
else if (undo_output)
{
const char *output = strdup (undo_output);
+ const char *orig_filename;
if (!output)
{
++failures;
@@ -358,11 +360,23 @@ main (int argc, char *argv[])
continue;
}
if (dso->filename != dso->soname)
- free ((char *) dso->filename);
+ orig_filename = dso->filename;
+ else
+ orig_filename = strdup (dso->filename);
+ if (!orig_filename)
+ {
+ ++failures;
+ close_dso (dso);
+ continue;
+ }
dso->filename = output;
+ if (update_dso (dso, orig_filename))
+ ++failures;
+ free ((char *) orig_filename);
+ continue;
}
- if (update_dso (dso))
+ if (update_dso (dso, NULL))
++failures;
}
diff --git a/src/prelink.c b/src/prelink.c
index ca6cc41..3723dfa 100644
--- a/src/prelink.c
+++ b/src/prelink.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -342,7 +342,7 @@ prelink_prepare (DSO *dso)
else
undo = move->old_to_new[undo];
- if (reopen_dso (dso, move))
+ if (reopen_dso (dso, move, NULL))
{
free (move);
return 1;
@@ -409,7 +409,7 @@ prelink_prepare (DSO *dso)
dso->undo.d_buf = NULL;
}
}
- else if (reopen_dso (dso, NULL))
+ else if (reopen_dso (dso, NULL, NULL))
return 1;
if (rinfo.rel_to_rela || rinfo.rel_to_rela_plt)
@@ -856,7 +856,7 @@ prelink (DSO *dso, struct prelink_entry *ent)
if (! dso_is_rdwr (dso) && dso->ehdr.e_type == ET_DYN)
{
- if (reopen_dso (dso, NULL))
+ if (reopen_dso (dso, NULL, NULL))
return 1;
}
diff --git a/src/prelink.h b/src/prelink.h
index 6518a91..7982d76 100644
--- a/src/prelink.h
+++ b/src/prelink.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -167,7 +167,7 @@ DSO * fdopen_dso (int fd, const char *name);
struct section_move *init_section_move (DSO *dso);
void add_section (struct section_move *move, int sec);
void remove_section (struct section_move *move, int sec);
-int reopen_dso (DSO *dso, struct section_move *move);
+int reopen_dso (DSO *dso, struct section_move *move, const char *);
int check_dso (DSO *dso);
int dso_is_rdwr (DSO *dso);
void read_dynamic (DSO *dso);
@@ -184,7 +184,7 @@ int adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust);
int adjust_mdebug (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust);
int finalize_mdebug (DSO *dso);
int relocate_dso (DSO *dso, GElf_Addr base);
-int update_dso (DSO *dso);
+int update_dso (DSO *dso, const char *);
int prepare_write_dso (DSO *dso);
int write_dso (DSO *dso);
int close_dso (DSO *dso);
diff --git a/src/undo.c b/src/undo.c
index fb08788..f9b0bd3 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -500,7 +500,7 @@ prelink_undo (DSO *dso)
if (undo == dso->ehdr.e_shnum)
{
if (undo_output)
- return reopen_dso (dso, NULL);
+ return reopen_dso (dso, NULL, undo_output);
error (0, 0, "%s does not have .gnu.prelink_undo section", dso->filename);
return 1;
}
@@ -516,7 +516,7 @@ prelink_undo (DSO *dso)
if (undo_sections (dso, undo, move, &rinfo, &ehdr, phdr, shdr))
goto error_out;
- if (reopen_dso (dso, move))
+ if (reopen_dso (dso, move, undo_output))
goto error_out;
if (find_reloc_sections (dso, &rinfo))
diff --git a/src/undoall.c b/src/undoall.c
index aef3318..4ce4670 100644
--- a/src/undoall.c
+++ b/src/undoall.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Red Hat, Inc.
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2002.
This program is free software; you can redistribute it and/or modify
@@ -74,7 +74,7 @@ undo_one (void **p, void *info)
close_dso (dso);
else
{
- if (update_dso (dso))
+ if (update_dso (dso, NULL))
{
dso = NULL;
goto error_out;
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 6ab3616..d434e35 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -9,7 +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 \
+ shuffle6.sh shuffle7.sh undo1.sh \
layout1.sh layout2.sh tls1.sh tls2.sh tls3.sh tls4.sh tls5.sh tls6.sh \
cxx1.sh quick1.sh quick2.sh cycle1.sh cycle2.sh deps1.sh deps2.sh \
undosyslibs.sh
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index 0097a63..f3f91bc 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -104,7 +104,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 \
+ shuffle6.sh shuffle7.sh undo1.sh \
layout1.sh layout2.sh tls1.sh tls2.sh tls3.sh tls4.sh tls5.sh tls6.sh \
cxx1.sh quick1.sh quick2.sh cycle1.sh cycle2.sh deps1.sh deps2.sh \
undosyslibs.sh
diff --git a/testsuite/undo1.sh b/testsuite/undo1.sh
new file mode 100755
index 0000000..d8436a5
--- /dev/null
+++ b/testsuite/undo1.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+. `dirname $0`/functions.sh
+rm -f undo1 undo1lib*.so undo1.log
+rm -f prelink.cache
+$CC -shared -O2 -fpic -o undo1lib1.so $srcdir/reloc1lib1.c
+$CC -shared -O2 -fpic -o undo1lib2.so $srcdir/reloc1lib2.c undo1lib1.so
+BINS="undo1"
+LIBS="undo1lib1.so undo1lib2.so"
+$CCLINK -o undo1 $srcdir/reloc1.c -Wl,--rpath-link,. undo1lib2.so
+savelibs
+echo $PRELINK ${PRELINK_OPTS--vm} ./undo1 > undo1.log
+$PRELINK ${PRELINK_OPTS--vm} ./undo1 >> undo1.log 2>&1 || exit 1
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` undo1.log && exit 2
+LD_LIBRARY_PATH=. ./undo1 || exit 3
+readelf -a ./undo1 >> undo1.log 2>&1 || exit 4
+# So that it is not prelinked again
+chmod -x ./undo1
+echo $PRELINK -uo undo1.undo undo1 >> undo1.log
+$PRELINK -uo undo1.undo undo1 >> undo1.log 2>&1 || exit 5
+cmp -s undo1.undo undo1.orig >> undo1.log 2>&1 || exit 6
+rm -f undo1.undo
+comparelibs >> undo1.log 2>&1 || exit 7