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: Sat, 19 Sep 2009 13:43:29 -0700
I have a problem using the -segaddr linker flag in an Xcode build. I
hope this is the appropriate group to post to; if not, please suggest
another. It is quite possible that I have a Cocoa bug of some sort,
but I wanted to make sure I was using the Xcode tools properly, so I
thought I would ask here first.
I am building a 64-bit 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.
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 guess, 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. 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.
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.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden