On Feb 24, 2016, at 5:26 PM, Jens Alfke <
email@hidden> wrote:
Is there a way to control which section of the executable a specific NSString literal goes into? I’ve tried using the ‘section’ attribute, but it has no effect:
I think that syntax is adding the attribute to the type, not to the variable. A pointer-to-something-in-a-section-X is not, itself, necessarily in section X. (But I'm never quite sure about the placement of __attribute__s.)
You can place the kFoo variable itself into a specific section by placing the annotation after its name. But all that does is move the statically-allocated CFString pointer to another section, which I assume isn't what you want.
As far as I know, there's no way to annotate a *value* using the __attribute__ notation, which is what you want if you want the actual textual stuff to go into another section. But a CFString/NSString literal actually creates stuff in two sections: the __cstring section (holding the C string value) and the __cfstring section (holding the statically-allocated CFConstantStringClassReference object, which is a few machine words long).
__attribute__((section(“__TEXT,__foo”))) static NSString* const kFoo = @“Foobar”;
The above doesn’t change where the string appears; there is no __TEXT,__foo section in the binary at all, and the string is still in the default __TEXT,__cstring section.
(FYI, although this doesn't apply to your case I don't think, I've found using repeated @string literals (via a #define, for maintainability) to be somewhat more compact than "static NSString * const foo". CFString literals (including @"foo" strings) are uniqued by the linker, so in general you'll end up sharing a single instance within the framework anyway.)
You can place a C string into a specific section using syntax like this:
static __attribute__((section("__TEXT,foo"))) const char foo_var[] = "Foo, forsooth.";
This works because the quoted string is acting as an initializer, rather than as a string literal, and foo_var[] is annotated as being in a specific section. (This also keeps the linker from merging identical cstrings, since array variables are distinct).
(We do this for reasons similar to yours, segregating some cold strings which we know wouldn't benefit from deduplication.)There's also an __attribute__((cold)), which is documented to be useful for situations like this, including basic-block reordering, but I don't know if the Xcode toolchain does anything with it.
If you're desperate, I suppose, you could cobble together your own CFConstantString instances pointing to string data in whatever section you like, using __asm__ blocks, but that might be brittle. :)