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