Problem using .zerofill / -segaddr to create very large segments
Problem using .zerofill / -segaddr to create very large segments
- Subject: Problem using .zerofill / -segaddr to create very large segments
- From: Jay Reynolds Freeman <email@hidden>
- Date: Mon, 21 Sep 2009 11:12:37 -0700
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