#ifdef HAS_UNIX_SEGMENT_HACK #include #include /* * baseaddr( ) returns the base address of the data segment on most Unix * systems. It's an ugly hack for info that should be provided by the OS. */ /* Does anyone use a pagesize < 256 bytes?? I'll bet not; * too small doesn't hurt */ #define LOG2_PAGESIZE 8 static jmp_buf env; static SIGNAL_TYPE fault( ) { sysv_signal(SIGSEGV, (SIGNAL_FUNCTION) fault); /* SysV style */ longjmp(env, 1); } static void * baseaddr( ) { char *low, *high, *at; char *sbrk( ); long x; SIGNAL_TYPE (*orig_signal)( ); if (getenv("SPICE_NO_DATASEG_CHECK")) return 0; low = 0; high = (char *) ((unsigned long) sbrk(0) & ~((1 << LOG2_PAGESIZE) - 1)); orig_signal = sysv_signal(SIGSEGV, (SIGNAL_FUNCTION) fault); do { at = (char *) ((((long)low >> LOG2_PAGESIZE) + ((long)high >> LOG2_PAGESIZE)) << (LOG2_PAGESIZE - 1)); # ifdef notdef at = (char *) ((((int) low + (int) high) / 2 + 0x7ff) & ~(long) 0xfff); /* nearest page */ # endif # ifdef notdef printf( "high = %#8x low = %#8x at = %#8x\n", high, low, at); # endif if (at == low || at == high) { break; } if (setjmp(env)) { low = at; continue; } else x = *at; if (setjmp(env)) { low = at; continue; } else *at = x; high = at; } while (1); # ifdef notdef printf ("start is at %#x, end is at %#x\n", high, sbrk(0)); # endif (void) signal(SIGSEGV, (SIGNAL_FUNCTION) orig_signal); return (void *) high; } # ifdef notdef main( ) { printf("testing\n"); printf("baseaddr: %#8x topaddr: %#8x\n", baseaddr( ), sbrk(0)); } # endif #else static void * baseaddr( ) { return 0; } #endif