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@csl.sri.com
If you want to be largely ignored by women, playing jazz guitar is
pretty good strategy... --- Bob Russell