Why is CODE32 defined on the x86-64 architecture? This architecture has 64 bit pointers, and it seems like it's only by luck that the bytecode interpreter normally works.
In particular, if you have the interpreter in a shared library, or (I assume) address-space randomization, then the jump table is located above the 4GB boundary, and the bytecode interpreter segfaults as soon as it tries to jump to the first instruction.
I had to apply the following patch to allow the bytecode interpreter to work in a shared library:
--- ocaml-3.09.0.orig/configure 2005-09-24 10:19:09.000000000 +0100 +++ ocaml-3.09.0/configure 2005-11-16 14:59:56.000000000 +0000 @@ -291,9 +291,7 @@ exe=".exe" ostype="Cygwin";; gcc*,x86_64-*-linux*) - bytecccompopts="-fno-defer-pop $gcc_warnings" - # Tell gcc that we can use 32-bit code addresses for threaded code - echo "#define ARCH_CODE32" >> m.h;; + bytecccompopts="-fno-defer-pop $gcc_warnings";; gcc*) bytecccompopts="-fno-defer-pop $gcc_warnings";; esac
Rich.
-- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com
> Why is CODE32 defined on the x86-64 architecture? This architecture > has 64 bit pointers, and it seems like it's only by luck that the > bytecode interpreter normally works.
No, it's not by luck: the x86-64 ABI defines several "code models", one of which -- the "small code model" -- guarantees that code and static data is in the lower 2G of the address space, and is the default for gcc (and I suspect other compilers as well).
I would have expected the dynamic loader to implement the small model like the static linker does, but from what you say it's not the case.
On Wed, Nov 16, 2005 at 04:21:23PM +0100, Xavier Leroy wrote: > > Why is CODE32 defined on the x86-64 architecture? This architecture > > has 64 bit pointers, and it seems like it's only by luck that the > > bytecode interpreter normally works.
> No, it's not by luck: the x86-64 ABI defines several "code models", > one of which -- the "small code model" -- guarantees that code and > static data is in the lower 2G of the address space, and is the > default for gcc (and I suspect other compilers as well).
> I would have expected the dynamic loader to implement the small model > like the static linker does, but from what you say it's not the case.
Thanks for looking into this.
It's definitely necessary for the dynamically linked code. See below for /proc/*/maps for an Apache process which contains a working instance of mod_caml.so and the bytecode interpreter libcamlrun.so recompiled with CODE32 undefined.
It might also be necessary if someone started to do address space randomization for example using PIE-compiled binaries, but I'm not certain about that.
On Wed, 2005-11-16 at 16:21 +0100, Xavier Leroy wrote: > I would have expected the dynamic loader to implement the small model > like the static linker does, but from what you say it's not the case.
The modelling constraints only apply to a statically linked image. The reason is that the constraints allow offsets for various instructions to 'fit' in the opcode.
Dynamically loaded *shared* libraries are accessed indirectly via tables .. so it doesn't matter where they're loaded.
-- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net