svn commit: r249441 - in user/dchagin/lemul/sys: amd64/linux32 compat/linux i386/linux

Dmitry Chagin dchagin at FreeBSD.org
Sat Apr 13 19:58:26 UTC 2013


Author: dchagin
Date: Sat Apr 13 19:58:24 2013
New Revision: 249441
URL: http://svnweb.freebsd.org/changeset/base/249441

Log:
  Slightly rewrite the VDSO symbols lookup and relocation:
  - to be a less strictly when relocating symbols to allow adjust all of them;
  - split the LINUX_VDSO_SYM_DEFINE macro on two counterparts and
  declare the vdso symbol to allow direct use.

Modified:
  user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c
  user/dchagin/lemul/sys/compat/linux/linux_vdso.c
  user/dchagin/lemul/sys/compat/linux/linux_vdso.h
  user/dchagin/lemul/sys/i386/linux/linux_sysvec.c

Modified: user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c	Sat Apr 13 19:02:58 2013	(r249440)
+++ user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c	Sat Apr 13 19:58:24 2013	(r249441)
@@ -225,9 +225,9 @@ struct linux32_ps_strings {
 	u_int ps_nenvstr;	/* the number of environment strings */
 };
 
-LINUX_VDSO_SYM_DEFINE(linux32_sigcode);
-LINUX_VDSO_SYM_DEFINE(linux32_rt_sigcode);
-LINUX_VDSO_SYM_DEFINE(linux32_vsyscall);
+LINUX_VDSO_SYM_INTPTR(linux32_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux32_rt_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux32_vsyscall);
 
 /*
  * If FreeBSD & Linux have a difference of opinion about what a trap
@@ -270,9 +270,7 @@ elf_linux_fixup(register_t **stack_base,
 
 	AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO_EHDR,
 	    imgp->proc->p_sysent->sv_shared_page_base);
-	AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO,
-	    LINUX_VDSO_SYM_VALUE(linux32_vsyscall));
-
+	AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO, linux32_vsyscall);
 	AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature);
 
 	/*
@@ -426,7 +424,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo
 	 * Build context to run handler in.
 	 */
 	regs->tf_rsp = PTROUT(fp);
-	regs->tf_rip = LINUX_VDSO_SYM_VALUE(linux32_rt_sigcode);
+	regs->tf_rip = linux32_rt_sigcode;
 	regs->tf_rflags &= ~(PSL_T | PSL_D);
 	regs->tf_cs = _ucode32sel;
 	regs->tf_ss = _udatasel;
@@ -550,7 +548,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t 
 	 * Build context to run handler in.
 	 */
 	regs->tf_rsp = PTROUT(fp);
-	regs->tf_rip = LINUX_VDSO_SYM_VALUE(linux32_sigcode);
+	regs->tf_rip = linux32_sigcode;
 	regs->tf_rflags &= ~(PSL_T | PSL_D);
 	regs->tf_cs = _ucode32sel;
 	regs->tf_ss = _udatasel;

Modified: user/dchagin/lemul/sys/compat/linux/linux_vdso.c
==============================================================================
--- user/dchagin/lemul/sys/compat/linux/linux_vdso.c	Sat Apr 13 19:02:58 2013	(r249440)
+++ user/dchagin/lemul/sys/compat/linux/linux_vdso.c	Sat Apr 13 19:58:24 2013	(r249441)
@@ -206,14 +206,7 @@ __elfN(linux_vdso_reloc)(struct sysentve
 				if (sym->st_shndx == SHN_UNDEF ||
 				    sym->st_shndx == SHN_ABS)
 					continue;
-
-				switch (ELF_ST_TYPE(sym->st_info)) {
-				case STT_OBJECT:
-				case STT_FUNC:
-				case STT_SECTION:
-				case STT_FILE:
-					sym->st_value += vdso_adjust;
-				}
+				sym->st_value += vdso_adjust;
 			}
 		}
 	}
@@ -239,11 +232,9 @@ __elfN(linux_vdso_lookup)(Elf_Ehdr *ehdr
 	symcnt = shdr[__elfN(symtabindex)].sh_size / sizeof(*sym);
 
 	for (i = 0; i < symcnt; ++i, ++sym) {
-		if (ELF_ST_TYPE(sym->st_info) != STT_FUNC)
-			continue;
 		symname = strtab + sym->st_name;
 		if (strncmp(vsym->symname, (char *)symname, vsym->size) == 0) {
-			vsym->value = (vm_offset_t)sym->st_value;
+			*vsym->ptr = (uintptr_t)sym->st_value;
 			break;
 		}
 	}

Modified: user/dchagin/lemul/sys/compat/linux/linux_vdso.h
==============================================================================
--- user/dchagin/lemul/sys/compat/linux/linux_vdso.h	Sat Apr 13 19:02:58 2013	(r249440)
+++ user/dchagin/lemul/sys/compat/linux/linux_vdso.h	Sat Apr 13 19:58:24 2013	(r249441)
@@ -34,7 +34,7 @@
 struct linux_vdso_sym {
 	SLIST_ENTRY(linux_vdso_sym) sym;
 	uint32_t	size;
-	vm_offset_t	value;
+	uintptr_t *	ptr;
 	char		symname[];
 };
 
@@ -44,16 +44,22 @@ void	__elfN(linux_vdso_fixup)(struct sys
 void	__elfN(linux_vdso_reloc)(struct sysentvec *, int);
 void	__elfN(linux_vdso_sym_init)(struct linux_vdso_sym *);
 
-#define	LINUX_VDSO_SYM_DEFINE(name)			\
-static struct linux_vdso_sym name = {			\
-	.symname	= #name,			\
-	.size		= sizeof(#name),		\
-	.value		= 0				\
-};							\
-SYSINIT(__elfN(name ## _sym_init), SI_SUB_EXEC,	\
-    SI_ORDER_FIRST, __elfN(linux_vdso_sym_init), &name);\
-struct __hack
+#define	LINUX_VDSO_SYM_INTPTR(name)				\
+uintptr_t name;							\
+LINUX_VDSO_SYM_DEFINE(name)
+
+#define	LINUX_VDSO_SYM_CHAR(name)				\
+const char * name;						\
+LINUX_VDSO_SYM_DEFINE(name)
 
-#define LINUX_VDSO_SYM_VALUE(name)	name.value	\
+#define	LINUX_VDSO_SYM_DEFINE(name)				\
+static struct linux_vdso_sym name ## sym = {			\
+	.symname	= #name,				\
+	.size		= sizeof(#name),			\
+	.ptr		= (uintptr_t *)&name			\
+};								\
+SYSINIT(__elfN(name ## _sym_init), SI_SUB_EXEC,			\
+    SI_ORDER_FIRST, __elfN(linux_vdso_sym_init), &name ## sym);	\
+struct __hack
 
 #endif	/* _LINUX_VDSO_H_ */

Modified: user/dchagin/lemul/sys/i386/linux/linux_sysvec.c
==============================================================================
--- user/dchagin/lemul/sys/i386/linux/linux_sysvec.c	Sat Apr 13 19:02:58 2013	(r249440)
+++ user/dchagin/lemul/sys/i386/linux/linux_sysvec.c	Sat Apr 13 19:58:24 2013	(r249441)
@@ -203,9 +203,9 @@ static int _bsd_to_linux_trapcode[] = {
      _bsd_to_linux_trapcode[(code)]: \
      LINUX_T_UNKNOWN)
 
-LINUX_VDSO_SYM_DEFINE(linux_sigcode);
-LINUX_VDSO_SYM_DEFINE(linux_rt_sigcode);
-LINUX_VDSO_SYM_DEFINE(linux_vsyscall);
+LINUX_VDSO_SYM_INTPTR(linux_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux_vsyscall);
 
 /*
  * If FreeBSD & Linux have a difference of opinion about what a trap
@@ -265,9 +265,7 @@ elf_linux_fixup(register_t **stack_base,
 
 	AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR,
 	    imgp->proc->p_sysent->sv_shared_page_base);
-	AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO,
-	    LINUX_VDSO_SYM_VALUE(linux_vsyscall));
-
+	AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO, linux_vsyscall);
 	AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
 
 	/*
@@ -529,7 +527,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo
 	 * Build context to run handler in.
 	 */
 	regs->tf_esp = (int)fp;
-	regs->tf_eip = LINUX_VDSO_SYM_VALUE(linux_rt_sigcode);
+	regs->tf_eip = linux_rt_sigcode;
 	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
 	regs->tf_cs = _ucodesel;
 	regs->tf_ds = _udatasel;
@@ -649,7 +647,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t 
 	 * Build context to run handler in.
 	 */
 	regs->tf_esp = (int)fp;
-	regs->tf_eip = LINUX_VDSO_SYM_VALUE(linux_sigcode);
+	regs->tf_eip = linux_sigcode;
 	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
 	regs->tf_cs = _ucodesel;
 	regs->tf_ds = _udatasel;


More information about the svn-src-user mailing list