|Version 5 (modified by gb, 6 years ago) (diff)|
On the PPC, there are addressing modes that make it easy to deal with 16-bit constants and 16-bit absolute addresses. CCL exploits this: things like NIL and T are 16-bit constants (and the addresses of things that are mapped into low memory); conditional calls to runtime support routines can use "branch absolute" instructions to call those routines (which are also mapped into the low 16 bits of the address space). Apple uses a similar scheme to reference critical library routines in Mac OS X (since the addressing mode generally involved signed 16-bit addresses, Apple's scheme uses addresses in the high 16 bits of the address space). That sort of thing is what the addressing modes are for, after all.
The Linux kernel provides a feature that can prevent a process from mapping addresses below a certain base address. The idea, apparently, is that this will prevent exploitation of undiscovered null pointer dereference bugs in the kernel.
The parameter in question is called mmap_min_addr; one can cat the file /proc/sys/vm/mmap_min_addr to see what the current setting is.
Some recent Linux distributions (including Fedora 9 and Ubuntu 8) ship with this value set to 65536. This has the effect of preventing processes from accessing the low 64K of their address spaces. Whether this makes sense or not on other architectures is debatable; on the PPC, it means that applications that want to exploit 16-bit PPC addressing are prohibited from doing so. We don't know if anyone involved in this decision thought about this issue or what they concluded if so. It's a little hard to believe that much thought went into that decision.
Fortunately, there are a few workarounds.
Processes running as root are not subject to the restriction. However, it's not reasonable to require rootly powers just to run CCL.
The value of mmap_min_addr can be changed by writing a new value to the file /proc/sys/vm/mmap_min_addr like so:
# echo 4096 >/proc/sys/vm/mmap_min_addr
This will persist only until the system is rebooted.
It should be possible to make a permanent fix by adding the line
to the file /etc/sysctl.conf. (This change will take effect on the next and subsequent reboots.)
The 4K value mentioned above will protect against certain (yet-to-be-discovered) NULL pointer deference bugs in the kernel, but will still allow applications to use low-memory addresses.
On some newer systems (Ubuntu 8.10, for instance, at least in the PS3 distribution), the 4K value doesn't work, although
# echo 0 >/proc/sys/vm/mmap_min_addr
will permit the lisp to run. (Setting this value to 0 doesn't necessarily make your system insecure. It might, however, make it possible or easier to exploit yet-to-be-discovered bugs in the Linux kernel.)
On the x86 platform, there's no architectural advantage to using 16-bit addresses (when it's even possible to do so). Version 1.1 of CCL/OpenMCL happened to use very similar/very low addresses (there was no reason not to); 1.2 and later use addresses above 64K (mostly because Windows restricts access to the low 64K for other reasons.)
It might be possible to rearchitect PPC CCL not to exploit this architectural feature, but the thought of doing so is not particularly attractive.
The distributed versions of Clozure CL are built on a FreeBSD 6.4 system; they should run unmodified on any 6.x system. (In general, the 64-bit version requires a 64-bit ("amd64") FreeBSD release; the 32-bit version of CCL should run on a 32-bit FreeBSD release or on a 64-bit release if the "lib32" 32-bit libraries are installed.)
FreeBSD changes library versions on major releases and executable files refer to the libraries that they depend on via versioned names, so the distributed CCL kernel (built on a 6.x system) won't run on a 7.x FreeBSD system (because the 6.x versions of the libraries it depends on aren't installed.) There are two ways to work around this:
- Install the "compat6x" package, which provides the 6.x libraries on a 7.x system. This can be done via the FreeBSD ports system:
$ cd /usr/ports/misc/compat6x $ sudo make install
- Build the kernel yourself on the 7.x system
$ cd ccl/lisp-kernel/freebsdx8632 # or freebsdx8664 $ make
FreeBSD doesn't provide the same level of support for multi-arch development (e.g., compiling 32-bit C code on 64-bit systems and vice versa) that Darwin, most Linux distributions, and Solaris offer; it's not generally possible to compile a 32-bit FreeBSD kernel on a 64-bit FreeBSD system. And vice versa.
It should be possible to run a 32-bit FreeBSD CCL on a 64-bit FreeBSD system and it generally is. Unfortunately, CCL triggers a bug that was introduced in the 7.1 release version of the 64-bit FreeBSD kernel (7.0 and 6.x are not affected.) See http://www.freebsd.org/cgi/query-pr.cgi?pr=130526 if you're interested in the gory details; the source patch in the responses to the bug report seems to work, so recompiling the 64-bit FreeBSD 7.1 kernel should enable 32-bit CCL to run on 64-bit FreeBSD 7.1.