[CRIU] [PATCH 9/9] pie/util-vdso: split parse_elf_symbols from vdso_fill_symtable

Dmitry Safonov dsafonov at virtuozzo.com
Wed Mar 30 08:12:30 PDT 2016


Impact: no functional changes, cleanup.

Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/pie/util-vdso.c | 104 +++++++++++++++++++++++++++------------------------
 1 file changed, 56 insertions(+), 48 deletions(-)

diff --git a/criu/pie/util-vdso.c b/criu/pie/util-vdso.c
index 439c7a13c9bf..13b2e5316db7 100644
--- a/criu/pie/util-vdso.c
+++ b/criu/pie/util-vdso.c
@@ -198,27 +198,73 @@ err_oob:
 	return -EFAULT;
 }
 
-int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t)
+static void parse_elf_symbols(uintptr_t mem, size_t size, Phdr_t *load,
+		struct vdso_symtable *t, uintptr_t dynsymbol_names,
+		Word_t *hash, Dyn_t *dyn_symtab)
 {
 	const char *vdso_symbols[VDSO_SYMBOL_MAX] = {
 		ARCH_VDSO_SYMBOLS
 	};
 
+	Word_t nbucket, nchain;
+	Word_t *bucket, *chain;
+
+	unsigned int i, j, k;
+	uintptr_t addr;
+
+	nbucket = hash[0];
+	nchain = hash[1];
+	bucket = &hash[2];
+	chain = &hash[nbucket + 2];
+
+	pr_debug("nbucket %lx nchain %lx bucket %lx chain %lx\n",
+		 (long)nbucket, (long)nchain, (unsigned long)bucket, (unsigned long)chain);
+
+	for (i = 0; i < VDSO_SYMBOL_MAX; i++) {
+		const char * symbol = vdso_symbols[i];
+		k = elf_hash((const unsigned char *)symbol);
+
+		for (j = bucket[k % nbucket]; j < nchain && chain[j] != STN_UNDEF; j = chain[j]) {
+			addr = mem + dyn_symtab->d_un.d_ptr - load->p_vaddr;
+			Sym_t *sym;
+			char *name;
+
+			addr += sizeof(Sym_t)*j;
+			if (__ptr_struct_oob(addr, sizeof(Sym_t), mem, size))
+				continue;
+			sym = (void *)addr;
+
+			if (ELF_ST_TYPE(sym->st_info) != STT_FUNC &&
+			    ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
+				continue;
+
+			addr = dynsymbol_names + sym->st_name;
+			if (__ptr_struct_oob(addr, VDSO_SYMBOL_MAX, mem, size))
+				continue;
+			name = (void *)addr;
+
+			if (builtin_strncmp(name, symbol, VDSO_SYMBOL_MAX))
+				continue;
+
+			builtin_memcpy(t->symbols[i].name, name, VDSO_SYMBOL_MAX);
+			t->symbols[i].offset = (unsigned long)sym->st_value - load->p_vaddr;
+			break;
+		}
+	}
+}
+
+int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t)
+{
 	Phdr_t *dynamic = NULL, *load = NULL;
 	Dyn_t *dyn_strtab = NULL;
 	Dyn_t *dyn_symtab = NULL;
 	Dyn_t *dyn_hash = NULL;
 	Word_t *hash = NULL;
 
-	Word_t *bucket, *chain;
-	Word_t nbucket, nchain;
-
+	uintptr_t dynsymbol_names;
 	uintptr_t addr;
 	int ret;
 
-	char *dynsymbol_names;
-	unsigned int i, j, k;
-
 	pr_debug("Parsing at %lx %lx\n", (long)mem, (long)mem + (long)size);
 
 	/*
@@ -247,57 +293,19 @@ int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t)
 	addr = mem + dyn_strtab->d_un.d_val - load->p_vaddr;
 	if (__ptr_oob(addr, mem, size))
 		goto err_oob;
-	dynsymbol_names = (void *)addr;
+	dynsymbol_names = addr;
 
 	addr = mem + dyn_hash->d_un.d_ptr - load->p_vaddr;
 	if (__ptr_struct_oob(addr, sizeof(Word_t), mem, size))
 		goto err_oob;
 	hash = (void *)addr;
 
-	nbucket = hash[0];
-	nchain = hash[1];
-	bucket = &hash[2];
-	chain = &hash[nbucket + 2];
-
-	pr_debug("nbucket %lx nchain %lx bucket %lx chain %lx\n",
-		 (long)nbucket, (long)nchain, (unsigned long)bucket, (unsigned long)chain);
-
-	for (i = 0; i < VDSO_SYMBOL_MAX; i++) {
-		const char * symbol = vdso_symbols[i];
-		k = elf_hash((const unsigned char *)symbol);
-
-		for (j = bucket[k % nbucket]; j < nchain && chain[j] != STN_UNDEF; j = chain[j]) {
-			addr = mem + dyn_symtab->d_un.d_ptr - load->p_vaddr;
-			Sym_t *sym;
-			char *name;
-
-			addr += sizeof(Sym_t)*j;
-			if (__ptr_struct_oob(addr, sizeof(Sym_t), mem, size))
-				continue;
-			sym = (void *)addr;
-
-			if (ELF_ST_TYPE(sym->st_info) != STT_FUNC &&
-			    ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
-				continue;
-
-			addr = (uintptr_t)dynsymbol_names + sym->st_name;
-			if (__ptr_struct_oob(addr, VDSO_SYMBOL_MAX, mem, size))
-				continue;
-			name = (void *)addr;
-
-			if (builtin_strncmp(name, symbol, VDSO_SYMBOL_MAX))
-				continue;
-
-			builtin_memcpy(t->symbols[i].name, name, VDSO_SYMBOL_MAX);
-			t->symbols[i].offset = (unsigned long)sym->st_value - load->p_vaddr;
-			break;
-		}
-	}
+	parse_elf_symbols(mem, size, load, t, dynsymbol_names, hash, dyn_symtab);
 
 	return 0;
 
 err_oob:
-	pr_err("Corrupted Elf data\n");
+	pr_err("Corrupted Elf symbols/hash\n");
 	return -EFAULT;
 }
 
-- 
2.7.4



More information about the CRIU mailing list