[CRIU] [PATCHv3 20/30] pie/restorer: add vdso_fill_symtable_compat for 32-bit vdso
Dmitry Safonov
dsafonov at virtuozzo.com
Tue Jun 28 12:24:13 PDT 2016
While restorering compatible application on x86-64, we need
to parse 32-bit vDSO. By that reason I need _three_ compiled
object versions for util-vdso:
- for native parasite it's util-vdso.o
- for compatible parasite it's compat/util-vdso.o
- for restorer it's util-vdso.o and util-vdso-elf32.o
Note, that I can't link compat/util-vdso.o to restorer, as it's
i386 ELF which ld can't link to x86_64 ELF file.
TODO: maybe I'll need to refactor and introduce generic
CONFIG_COMPAT instead of those defined(CONFIG_X86_32).
Fixes:
pie: 27504: vdso: Mapping compatible vDSO at 0x25000
pie: 27504: Remap 0x7f3de3efa000->0x8048000 len 0x1000
...
pie: 27504: vdso: Parsing at 0xf7776000 0xf7778000
pie: 27504: Error (pie/util-vdso.c:87): vdso: Elf header magic mismatch
pie: 27504: Error (pie/restorer.c:1540): Restorer fail 27504
(00.029188) Error (cr-restore.c:988): 27504 exited, status=1
(00.033072) Error (cr-restore.c:1870): Restoring FAILED.
Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
criu/include/parasite-vdso.h | 2 +-
criu/include/util-vdso.h | 4 ++++
criu/pie/Makefile.library | 3 +++
criu/pie/parasite-vdso.c | 22 +++++++++++++++++++---
criu/pie/restorer.c | 3 ++-
criu/pie/util-vdso-elf32.c | 1 +
6 files changed, 30 insertions(+), 5 deletions(-)
create mode 120000 criu/pie/util-vdso-elf32.c
diff --git a/criu/include/parasite-vdso.h b/criu/include/parasite-vdso.h
index d50319048264..4f25f57d3573 100644
--- a/criu/include/parasite-vdso.h
+++ b/criu/include/parasite-vdso.h
@@ -83,7 +83,7 @@ extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, uns
int vdso_map_compat(unsigned long map_at);
extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
- VmaEntry *vmas, size_t nr_vmas);
+ VmaEntry *vmas, size_t nr_vmas, bool compat_vdso);
#else /* CONFIG_VDSO */
#define vdso_do_park(sym_rt, park_at, park_size) (0)
diff --git a/criu/include/util-vdso.h b/criu/include/util-vdso.h
index 43f7549c822e..63bc70d79f3e 100644
--- a/criu/include/util-vdso.h
+++ b/criu/include/util-vdso.h
@@ -88,6 +88,10 @@ static inline unsigned long vvar_vma_size(struct vdso_symtable *t)
return t->vvar_end - t->vvar_start;
}
+#if defined(CONFIG_X86_32)
+# define vdso_fill_symtable vdso_fill_symtable_compat
+#endif
+
extern int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t);
#endif /* __CR_UTIL_VDSO_H__ */
diff --git a/criu/pie/Makefile.library b/criu/pie/Makefile.library
index ecd862385222..288594a64959 100644
--- a/criu/pie/Makefile.library
+++ b/criu/pie/Makefile.library
@@ -9,6 +9,9 @@ ifeq ($(ARCH),x86)
target += compat
CFLAGS_native += -DCONFIG_X86_64
CFLAGS_compat += -fno-pic -m32 -DCONFIG_X86_32
+
+ native-lib-y += util-vdso-elf32.o
+ CFLAGS_util-vdso-elf32.o += -DCONFIG_X86_32
endif
OBJS += log-simple.o util-fd.o util.o
diff --git a/criu/pie/parasite-vdso.c b/criu/pie/parasite-vdso.c
index b5d12f1e1ca7..9310b0426a3a 100644
--- a/criu/pie/parasite-vdso.c
+++ b/criu/pie/parasite-vdso.c
@@ -81,16 +81,32 @@ int vdso_map_compat(unsigned long map_at)
ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
return ret;
}
+
+extern int vdso_fill_symtable_compat(uintptr_t mem, size_t size,
+ struct vdso_symtable *t);
+int __vdso_fill_symtable(uintptr_t mem, size_t size,
+ struct vdso_symtable *t, bool compat_vdso)
+{
+ if (compat_vdso)
+ return vdso_fill_symtable_compat(mem, size, t);
+ else
+ return vdso_fill_symtable(mem, size, t);
+}
#else
int vdso_map_compat(unsigned long map_at)
{
return 0;
}
+int __vdso_fill_symtable(uintptr_t mem, size_t size,
+ struct vdso_symtable *t, bool __always_unused compat_vdso)
+{
+ return vdso_fill_symtable(mem, size, t);
+}
#endif
int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
- VmaEntry *vmas, size_t nr_vmas)
+ VmaEntry *vmas, size_t nr_vmas, bool compat_vdso)
{
VmaEntry *vma_vdso = NULL, *vma_vvar = NULL;
struct vdso_symtable s = VDSO_SYMTABLE_INIT;
@@ -125,8 +141,8 @@ int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
/*
* Find symbols in vDSO zone read from image.
*/
- if (vdso_fill_symtable((uintptr_t)vma_vdso->start,
- vma_entry_len(vma_vdso), &s))
+ if (__vdso_fill_symtable((uintptr_t)vma_vdso->start,
+ vma_entry_len(vma_vdso), &s, compat_vdso))
return -1;
/*
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index b40bc346e279..96a44c8f56d0 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1216,7 +1216,8 @@ long __export_restore_task(struct task_restore_args *args)
vma_entry_is(&args->vmas[i], VMA_AREA_VVAR)) {
if (vdso_proxify("dumpee", &args->vdso_sym_rt,
args->vdso_rt_parked_at,
- i, args->vmas, args->vmas_n))
+ i, args->vmas, args->vmas_n,
+ args->compatible_mode))
goto core_restore_end;
break;
}
diff --git a/criu/pie/util-vdso-elf32.c b/criu/pie/util-vdso-elf32.c
new file mode 120000
index 000000000000..97928c05535d
--- /dev/null
+++ b/criu/pie/util-vdso-elf32.c
@@ -0,0 +1 @@
+util-vdso.c
\ No newline at end of file
--
2.9.0
More information about the CRIU
mailing list