Re: Problem using .zerofill / -segaddr to create very large segments
Re: Problem using .zerofill / -segaddr to create very large segments
- Subject: Re: Problem using .zerofill / -segaddr to create very large segments
- From: Brian Mastenbrook <email@hidden>
- Date: Mon, 21 Sep 2009 14:24:04 -0500
Jay,
I understand what it is you're trying to do here, since I've been
through this battle myself. Long, long ago I implemented this solution
for SBCL by creating a Mach-O object file directly; at the time, the
linker didn't even have a .zerofill directive if I remember correctly.
This has since been removed from the main SBCL trunk (which I think
was a mistake), but you can view the elements of the solution here:
http://sbcl.cvs.sourceforge.net/viewvc/sbcl/sbcl/src/runtime/ppc-darwin-mkrospace.c?view=markup
- creates a .o file with N zero-fill segments of zero size
http://sbcl.cvs.sourceforge.net/viewvc/sbcl/sbcl/src/runtime/ppc-darwin-fix-rospace.c?view=markup
- opens the SBCL executable, grovels through the sections, finds the
zero-fill segments, and fixes the size and start address parameters
This two-phase process was necessary because `nm' & friends had bugs
with handling of zero-fill segments, and didn't understand that the
size of the segment didn't indicate a number of bytes to be skipped in
the object file. `nm' has gotten a little bit smarter about this these
days; it still doesn't like seeing a size on a zero-fill segment, but
it doesn't barf on it anymore.
I've whipped up a quick adaptation of this for x86_64, which you can
view here:
http://paste.lisp.org/display/87459
I used this program to create an object with a 161GB reservation, and
it seemed to work fine in a very cursory test.
-- Brian
On Sep 21, 2009, at 1:12 PM, Jay Reynolds Freeman wrote:
I have a problem which might be Xcode, Darwin, or even Cocoa; I ran
this posting past the Xcode list a few days ago with no insightful
developments, so my next thought was to ask here if anyone had a
clue...
I have a problem using the -segaddr linker flag in an Xcode build.
I am building a 64-bit Macintosh application using Xcode 3.2 on
MacOS 10.6.1, on an early-2008 model Mac Pro. The build targets
architecture x86_64, uses the LLVM GCC 4.2 compiler, has a Mac OS X
Deployment Target of Mac OS X 10.6, and if you would like to know
any other build settings, let me hear from you.
My problem concerns keeping a block of memory out of the clutches of
the storage allocator (malloc, new, et cetera), so that I can use it
for mmap. I do have a solution to do that, which DOES work, which is:
1) Include in my build a ".s" file that contains
appropriate .zerofill directives to define a segment large enough
for my purposes.
2) Tell the linker where to put that segment by putting, e.g, "-
segaddr __WSS 0x10000000000" in the "Other Linker Flags" entry of
the build rules pane of the Xcode information panel for the target
for my application.
This all works fine, and has been working for months, and I am not
having any problem with mmap (knock on wood).
My problem is that I need a *very* large segment -- at the moment I
am using 160 Gigabytes (segment length #x2800000000 bytes, and
remember, this is 64-bit code). I need to make the segment even
larger for a forthcoming upgrade of the application, and I appear to
be running up against some kind of limitation on the total size of
segments created in this manner. It has been decades since I have
written Intel x86 assembler in any form, and I have always regarded
the linker as rather a black box and not tried to use unusual flags.
So I hope I am merely making some embarrassingly simple mistake, but
I have checked the man pages and the web, and I cannot find any
useful clues.
(By the way, since someone asked on the Xcode list, I will mention
that I need a large shared segment for use in a parallel -- separate
Unix processes -- Lisp system with shared Lisp main memory. I would
be happy to talk about it off-list if anyone is interested.)
Here are a few more details:
I haven't been able to make the .zerofill directive understand 64-
bit numbers -- #x1234567890LL and similar suffixes result in errors
or incorrect linkages. So my ".s" file actually contains a lot of
adjacent .zerofills, as follows:
.zerofill __WSS, __Wss000, _WraithSpace, 0x40000000
.zerofill __WSS, __Wss001, _zz001, 0x40000000
.zerofill __WSS, __Wss002, _zz002, 0x40000000
...
.zerofill __WSS, __Wss156, _zz156, 0x40000000
.zerofill __WSS, __Wss157, _zz157, 0x40000000
.zerofill __WSS, __Wss158, _zz158, 0x40000000
.zerofill __WSS, __Wss159, _zz159, 0x40000000
That is a total of 160 one-Gigabyte blocks, all in segment __WSS.
That works fine, and has been working for months.
The problem comes if I add even one more .zerofill block at the end
of that file, creating a segment of 161 GByte instead of 160 GByte:
.zerofill __WSS, __Wss160, _zz160, 0x40000000
In that case, the Xcode build completes (I do a clean and a complete
fresh build) with no errors reported, BUT I get run-time errors when
I launch the application, while the framework is still getting
going, long before the actual mmap has taken place. Here is the
first of many run-time errors, as reported in the Console Messages
log. The error kind of makes sense, in that my application does
indeed have the indicated class and should indeed be trying to load
it at launch time (but why increasing the segment size has made it
impossible to load the class is beyond me):
9/19/09 1:06:32 PM Wraith Scheme[35427] Unknown class JRF2NSTextView
in Interface Builder file at path /Users/JayFreeman/Developer/Scheme/
WraithScheme.64/WraithCocoa/build/Release/Wraith Scheme.app/Contents/
Resources/English.lproj/MainMenu.nib.
If I remove the extra .zerofill, re-clean and rebuild, all is well
again.
I have tried changing the address for __WSS that I provide via the -
segaddr flag. I have also tried adding the additional reserved
memory in a different segment (eg, .zerofill __MMS, __Mms000 _mm000,
0x40000000) with an additional -segaddr flag in "Other Linker
Flags". Neither works.
It looks like the system doesn't like to have the total size of
reserved segments larger than about 160 GByte. (As you may have
guessed, I learned about this limit by tripping over it; it is no
accident that my present ".s" file defines precisely 160 GByte of
reserved segment.)
I am leaning toward thinking this is an Xcode problem, but I would
be eager to know whether anyone can find any obvious error in my use
of .zerofill and -segaddr, or whether anyone can think of anything
in the Darwin body of code that might cause this phenomenon.
Pointers to more documentation would also be very useful; I have
spent a while searching, but I am such a stranger to x86 assembler
and to the linker that I may very well be using the wrong search
keywords, and my knowledge of Darwin _per_se_ is rather, er,
unevolved ...
Thank you very much.
-- Jay Reynolds Freeman
---------------------
email@hidden
http://web.mac.com/jay_reynolds_freeman (personal web site)
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
--
Brian Mastenbrook
email@hidden
http://brian.mastenbrook.net/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden