Question about malloc, mmap etc.

Fred Gilham gilham at csl.sri.com
Wed Jul 23 20:09:16 PDT 2003


I'm trying to do a little system hacking on CMU Lisp.  Currently CMU
Lisp has a minimum of two files needed to execute.  One is a program
usually called "lisp" that the OS runs, which basically a loader for
the other file, a lisp.core file that contains the actual lisp system.

People have been asking for a way to make a "lisp executable" meaning
putting everything into a single file.  It's more than just tidiness
--- the core and loader have to stay synchronized, and in the normal
process of keeping the system up to date you can sometimes wind up
with an old core file that you can no longer run because you don't
have the corresponding loader any more and it would be tedious to
recover it.

Anyway I created a utility that post-processes the lisp.core file,
creating three ELF compatible ".o" files, one for each memory space
that lisp uses.  I then hacked a linker script so that GNU ld will put
these .o files in the executable and add the proper program headers.
It all worked, and I can actually run the resulting executable.
Unfortunately it doesn't get far.

The first time it calls malloc, malloc tries to call sbrk (I think
it's sbrk) twice and those calls return invalid argument errors.
Malloc then returns 0.  I used ktrace and the "U" malloc_option to
determine this --- the calls show up as follows:


 89021 testit   CALL  readlink(0x680bbf14,0xbfbff3b0,0x3f)
 89021 testit   NAMI  "/etc/malloc.conf"
 89021 testit   RET   readlink -1 errno 2 No such file or directory
 89021 testit   CALL  utrace(0xbfbff3a4,0xc)
 89021 testit   USER  12  00 00 00 00 00 00 00 00 00 00 00 00
 89021 testit   RET   utrace 0
 89021 testit   CALL  mmap(0,0x1000,0x3,0x1002,0xffffffff,0,0,0)
 89021 testit   RET   mmap 1745698816/0x680d4000
 89021 testit   CALL  break(0x8067000)
 89021 testit   RET   break -1 errno 22 Invalid argument
 89021 testit   CALL  break(0x81e6000)
 89021 testit   RET   break -1 errno 22 Invalid argument
 89021 testit   CALL  utrace(0xbfbff414,0xc)
 89021 testit   USER  12  00 00 00 00 00 00 18 00 00 00 00 00
 89021 testit   RET   utrace 0



I tried to look at the source to see if I could find out what is
causing the "break" calls to return EINVAL but I couldn't find the
actual code that does these system calls.  The man page says EINVAL
gets returned when "The requested break value was beyond the beginning
of the data segment," which doesn't quite make sense to me.

The segments my program creates are at 0x10000000, 0x28f00000 and
0x48000000 if that makes a difference.

Anyway my question is whether anyone knows why this might be happening
or if someone can point me in the right direction to find out.

Thanks for any help!

-- 
Fred Gilham                                     gilham at csl.sri.com
If you want to be largely ignored by women, playing jazz guitar is
pretty good strategy...  --- Bob Russell


More information about the freebsd-stable mailing list