[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On 2006-11-24, Peter Wang <tjaden@xxxxxxxxxx> wrote:
>
> I tried compiling Allegro 4.2 SVN on Solaris, and there were a bunch of
> problems with the mprotect() stuff. It seems the proper way to get the
> memory page size is using sysconf(_SC_PAGESIZE) instead of the PAGE_SIZE
> macro (even on Linux). A quick patch follows (it's got some minor fixes to
> _unix_get_executable_name() intermingled in it).
> Note I didn't actually test that the compiled programs work on Solaris,
> as I did it remotely.
Forgot to attach :-P I've committed it.
Peter
Index: src/i386/opcodes.h
===================================================================
--- src/i386/opcodes.h (revision 7574)
+++ src/i386/opcodes.h (working copy)
@@ -29,7 +29,6 @@
#define __USE_GNU /* for mremap */
#include <stdlib.h> /* for mkstemp */
#include <unistd.h> /* for unlink */
- #include <sys/user.h> /* for PAGE_SIZE */
#include <sys/mman.h> /* for mmap */
static void *_exec_map;
@@ -38,13 +37,15 @@
static int _map_fd;
#define GROW_GEN_CODE_BUF(size) \
+ do { \
+ size_t page_size = _unix_get_page_size(); \
if (!_map_size) { \
/* Create backing file. FIXME: error-checking, but how? */ \
char tempfile_name[] = "/tmp/allegroXXXXXX"; \
_map_fd = mkstemp(tempfile_name); \
unlink(tempfile_name); \
/* Grow backing file to multiple of page size */ \
- _map_size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); \
+ _map_size = (size + (page_size-1)) & ~(page_size-1); \
ftruncate(_map_fd, _map_size); \
/* And create the 2 mappings */ \
_exec_map = mmap(0, _map_size, PROT_EXEC | PROT_READ, MAP_SHARED, \
@@ -55,12 +56,13 @@
else if (size > _map_size) { \
int old_size = _map_size; \
/* Grow backing file to multiple of page size */ \
- _map_size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); \
+ _map_size = (size + (page_size-1)) & ~(page_size-1); \
ftruncate(_map_fd, _map_size); \
/* And remap the 2 mappings */ \
_exec_map = mremap(_exec_map, old_size, _map_size, MREMAP_MAYMOVE); \
_rw_map = mremap(_rw_map, old_size, _map_size, MREMAP_MAYMOVE); \
- }
+ } \
+ } while (0)
#define GEN_CODE_BUF _rw_map
#else
Index: src/i386/icsprite.c
===================================================================
--- src/i386/icsprite.c (revision 7574)
+++ src/i386/icsprite.c (working copy)
@@ -16,18 +16,28 @@
*/
+#include <stdio.h>
#include <string.h>
#include "allegro.h"
#include "allegro/internal/aintern.h"
#include "opcodes.h"
+#ifdef ALLEGRO_UNIX
+ #include "allegro/platform/aintunix.h" /* for _unix_get_page_size */
+#endif
+
#ifdef ALLEGRO_WINDOWS
#include "winalleg.h" /* For VirtualProtect */
#endif /* ifdef ALLEGRO_WINDOWS */
+#ifdef HAVE_MPROTECT
+ #include <sys/types.h>
+ #include <sys/mman.h>
+#endif /* ifdef HAVE_MPROTECT */
+
/* compile_sprite:
* Helper function for making compiled sprites.
*/
@@ -303,7 +313,8 @@
}
#elif defined(HAVE_MPROTECT)
{
- char *aligned_p = (char *)((unsigned long)p & ~(PAGE_SIZE-1ul));
+ long page_size = _unix_get_page_size();
+ char *aligned_p = (char *)((unsigned long)p & ~(page_size-1ul));
if (mprotect(aligned_p, compiler_pos + ((char *)p - aligned_p),
PROT_EXEC|PROT_READ|PROT_WRITE)) {
perror("allegro-error: mprotect failed during compile sprite!");
Index: src/i386/istretch.c
===================================================================
--- src/i386/istretch.c (revision 7574)
+++ src/i386/istretch.c (working copy)
@@ -26,6 +26,10 @@
#include "allegro/internal/aintern.h"
#include "opcodes.h"
+#ifdef ALLEGRO_UNIX
+ #include "allegro/platform/aintunix.h" /* for _unix_get_page_size */
+#endif
+
#ifdef ALLEGRO_WINDOWS
#include "winalleg.h" /* For VirtualProtect */
#endif /* ifdef ALLEGRO_WINDOWS */
@@ -35,7 +39,6 @@
#ifdef HAVE_MPROTECT
#include <sys/types.h>
#include <sys/mman.h>
- #include <sys/user.h>
#endif /* ifdef HAVE_MPROTECT */
@@ -452,7 +455,7 @@
VirtualProtect(_scratch_mem, _scratch_mem_size, PAGE_EXECUTE_READWRITE, &old_protect);
#elif defined(HAVE_MPROTECT) && !defined(USE_MMAP_GEN_CODE_BUF)
{
- char *p = (char *)((uintptr_t)_scratch_mem & ~(PAGE_SIZE-1ul));
+ char *p = (char *)((uintptr_t)_scratch_mem & ~(_unix_get_page_size() - 1ul));
if (mprotect(p, _scratch_mem_size + ((char *)_scratch_mem - p),
PROT_EXEC|PROT_READ|PROT_WRITE))
perror("allegro-error: mprotect failed during stretched blit!");
Index: src/unix/usystem.c
===================================================================
--- src/unix/usystem.c (revision 7574)
+++ src/unix/usystem.c (working copy)
@@ -323,9 +323,6 @@
struct prpsinfo psinfo;
int fd;
#endif
- #if defined ALLEGRO_HAVE_SV_PROCFS || defined ALLEGRO_SYS_GETEXECNAME
- char *s;
- #endif
char linkname[1024];
char filename[1024];
struct stat finfo;
@@ -334,7 +331,8 @@
int len;
#ifdef ALLEGRO_HAVE_GETEXECNAME
- s = getexecname();
+ {
+ const char *s = getexecname();
if (s) {
if (s[0] == '/') { /* Absolute path */
do_uconvert (s, U_ASCII, output, U_CURRENT, size);
@@ -345,7 +343,7 @@
return;
}
}
- s = NULL;
+ }
#endif
/* We need the PID in order to query procfs */
@@ -353,7 +351,7 @@
/* Try a Linux-like procfs */
/* get symolic link to executable from proc fs */
- sprintf (linkname, "/proc/%d/exe", pid);
+ sprintf (linkname, "/proc/%d/exe", (int)pid);
if (stat (linkname, &finfo) == 0) {
len = readlink (linkname, filename, sizeof(filename)-1);
if (len>-1) {
@@ -366,7 +364,7 @@
/* Use System V procfs calls if available */
#ifdef ALLEGRO_HAVE_SV_PROCFS
- sprintf (linkname, "/proc/%d/exe", pid);
+ sprintf (linkname, "/proc/%d/exe", (int)pid);
fd = open(linkname, O_RDONLY);
if (!fd == -1) {
ioctl(fd, PIOCPSINFO, &psinfo);
@@ -388,7 +386,7 @@
*/
/* Skip other args */
- s = strchr(psinfo.pr_psargs, ' ');
+ char *s = strchr(psinfo.pr_psargs, ' ');
if (s) s[0] = '\0';
if (_find_executable_file(psinfo.pr_psargs, output, size))
return;
@@ -402,7 +400,7 @@
/* Last resort: try using the output of the ps command to at least find */
/* the name of the file if not the full path */
- uszprintf (linkname, sizeof(linkname), "ps -p %d", pid);
+ uszprintf (linkname, sizeof(linkname), "ps -p %d", (int)pid);
do_uconvert (linkname, U_CURRENT, filename, U_ASCII, size);
pipe = popen(filename, "r");
if (pipe) {
@@ -450,3 +448,18 @@
#endif
+
+
+/* _unix_get_page_size:
+ * Get size of a memory page in bytes. If we can't do it, we make a guess.
+ */
+size_t _unix_get_page_size(void)
+{
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ long page_size = sysconf(_SC_PAGESIZE);
+#else
+ long page_size = -1;
+#endif
+
+ return (page_size == -1) ? 4096 : page_size;
+}
Index: include/allegro/platform/aintunix.h
===================================================================
--- include/allegro/platform/aintunix.h (revision 7574)
+++ include/allegro/platform/aintunix.h (working copy)
@@ -78,6 +78,11 @@
/* File system helpers */
AL_FUNC(void, _unix_guess_file_encoding, (void));
+
+ /* Get size of a memory page in bytes */
+ AL_FUNC(size_t, _unix_get_page_size, (void));
+
+
#ifdef ALLEGRO_WITH_XWINDOWS
AL_FUNCPTR(void, _xwin_keyboard_interrupt, (int pressed, int code));
AL_FUNCPTR(void, _xwin_keyboard_focused, (int focused, int state));
Index: configure.in
===================================================================
--- configure.in (revision 7574)
+++ configure.in (working copy)
@@ -714,6 +714,7 @@
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(mmap mprotect memcmp mkstemp stricmp strlwr strupr vprintf stat64)
+AC_CHECK_FUNCS(sysconf)
dnl Tweak header files for library build
CFLAGS="$CFLAGS -DALLEGRO_LIB_BUILD"