Get bsd-user host page protection code working on FreeBSD hosts
Use kinfo_getvmmap(3) on FeeBSD >= 7.x and /compat/linux/proc on older FreeBSD. (kinfo_getvmmap is preferred since /compat/linux/proc is usually only mounted on hosts also using the Linuxolator.) This patch is a bit hacky because the includes needed for kinfo_getvmmap conflict with other definitions in exec.c by default so I had to `trick around' a little, but I built the result in FreeBSD 6.4-stable and 7.2-stable tbs and on 8-stable on the host so the hacks at least should be stable. (If this is a problem maybe we could also move the kinfo_getvmmap invocations into a seperate source file but that would be more work...) Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
b035ffd118
commit
f01576f185
|
@ -332,6 +332,8 @@ FreeBSD)
|
||||||
make="gmake"
|
make="gmake"
|
||||||
audio_drv_list="oss"
|
audio_drv_list="oss"
|
||||||
audio_possible_drivers="oss sdl esd pa"
|
audio_possible_drivers="oss sdl esd pa"
|
||||||
|
# needed for kinfo_getvmmap(3) in libutil.h
|
||||||
|
LIBS="-lutil $LIBS"
|
||||||
;;
|
;;
|
||||||
DragonFly)
|
DragonFly)
|
||||||
bsd="yes"
|
bsd="yes"
|
||||||
|
|
50
exec.c
50
exec.c
|
@ -42,6 +42,21 @@
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
#include <qemu.h>
|
#include <qemu.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if __FreeBSD_version >= 700104
|
||||||
|
#define HAVE_KINFO_GETVMMAP
|
||||||
|
#define sigqueue sigqueue_freebsd /* avoid redefinition */
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <machine/profile.h>
|
||||||
|
#define _KERNEL
|
||||||
|
#include <sys/user.h>
|
||||||
|
#undef _KERNEL
|
||||||
|
#undef sigqueue
|
||||||
|
#include <libutil.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_TB_INVALIDATE
|
//#define DEBUG_TB_INVALIDATE
|
||||||
|
@ -275,11 +290,45 @@ static void page_init(void)
|
||||||
|
|
||||||
#if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
|
#if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_KINFO_GETVMMAP
|
||||||
|
struct kinfo_vmentry *freep;
|
||||||
|
int i, cnt;
|
||||||
|
|
||||||
|
freep = kinfo_getvmmap(getpid(), &cnt);
|
||||||
|
if (freep) {
|
||||||
|
mmap_lock();
|
||||||
|
for (i = 0; i < cnt; i++) {
|
||||||
|
unsigned long startaddr, endaddr;
|
||||||
|
|
||||||
|
startaddr = freep[i].kve_start;
|
||||||
|
endaddr = freep[i].kve_end;
|
||||||
|
if (h2g_valid(startaddr)) {
|
||||||
|
startaddr = h2g(startaddr) & TARGET_PAGE_MASK;
|
||||||
|
|
||||||
|
if (h2g_valid(endaddr)) {
|
||||||
|
endaddr = h2g(endaddr);
|
||||||
|
page_set_flags(startaddr, endaddr, PAGE_RESERVED);
|
||||||
|
} else {
|
||||||
|
#if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
|
||||||
|
endaddr = ~0ul;
|
||||||
|
page_set_flags(startaddr, endaddr, PAGE_RESERVED);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(freep);
|
||||||
|
mmap_unlock();
|
||||||
|
}
|
||||||
|
#else
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
last_brk = (unsigned long)sbrk(0);
|
last_brk = (unsigned long)sbrk(0);
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||||
|
f = fopen("/compat/linux/proc/self/maps", "r");
|
||||||
|
#else
|
||||||
f = fopen("/proc/self/maps", "r");
|
f = fopen("/proc/self/maps", "r");
|
||||||
|
#endif
|
||||||
if (f) {
|
if (f) {
|
||||||
mmap_lock();
|
mmap_lock();
|
||||||
|
|
||||||
|
@ -304,6 +353,7 @@ static void page_init(void)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
mmap_unlock();
|
mmap_unlock();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue