@MLton load-word and MacOSX 10.7 (Lion)

Matthew Fluet <[email protected]> Tue, 12 Jun 2012 17:08:20 -0400
Newsgroups gmane.comp.lang.ml.mlton.devel
Message-ID <CAMrhFL57qDUywJ4Eipf3yQgCTDPXFFsLGzndXy=zhR7+S-x8wA@mail.gmail.com>
"@MLton load-world" is currently broken (by default) for 64-bit
executables on MacOSX 10.7 (Lion).

The problem seems to be that MLton is generating position-independent
code (PIC) code for executables and Lion introduced address-space
layout randomization (ASLR) for executables.  That is, the code
segment of an executable is loaded at a random address each time that
it is executed.  Unfortunately, the Basis Library implementation
fetches the address of the static gcState struct early in the
evaluation of the Basis Library, saving the result in an SML variable.
 Subsequent accesses (mostly, just passing the address to primitives
and/or imported C functions that need the gcState) deliver the address
of the static gcState struct from the SML variable.  This causes a
problem with @MLton load-world, because the address is loaded from the
saved world, but that address corresponds to a different execution of
the executable, hence a segfault upon the first access through that
invalid address.

The expedient solution is to use '-link-opt -fno-PIE' to suppress the
generation of position-independent executables, at least for programs
that need to save and load worlds.  (Oddly, '-link-opt -W,-no_pie'
seems to have no effect.)

It isn't clear that there is a simple way to support PIE and
load-world.  As noted above, the Basis Library implementation fetches
the address early:

      val gcState = #1 _symbol "gcStateAddress" private: t GetSet.t; ()

Behind the scenes, this desugars to an FFI_Symbol primitive (that
evaluated to the address of the symbol) and CPointer_{get,set}X
primitives.  The compiler treats FFI_Symbol as "Functional", so it is
free to lift the FFI_Symbol primitive to the top-level and evaluate it
only once.  (Fetching via CPointer_get, though, is treated as
"DependsOnState", since the symbol is considered a mutable field.)
While it would be possible to perform the fetch immediately before
each use of the address of the gcState struct, that doesn't solve the
problem that the address at which the address is stored (i.e., the
address of the gcStateAddress symbol) will have been saved in the
world from the world-saving execution.  Treating FFI_Symbol as
"DependsOnState" seems a bit draconian.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/