问题
How can I move sections out of the __TEXT
segment and into a new segment for a mach-o binary? The reason I'm asking is that I'm trying to make my iPhone app smaller, and the iOS App Store encrypts the __TEXT
segment of it prior to compression so that it doesn't compress at all. If I can move all the non-executable sections out of that segment and into a new read-only segment, then I can trim the size of my app by about 9%.
回答1:
On linker level
As already mentioned in @meisel answer this can be done through: So the value to set would be:
-Wl,-rename_section,__TEXT,__sectionName,__NEW_SEGMENT_NAME,__newSectionName
if segment permisions need to be adjusted
-segprot,__NEW_SEGMENT_NAME,rx,rx
Be careful with rwx
for executable code, the app will be immediately killed by iOS XNU kernel if rxw
running code is detected. It's still fine for simulator. This blog post covers some usage examples.
On function prototype level
Assuming you're using Objective-C (or C for that matter) you can use __attribute__ section(...)
.
Syntax:__attribute__ ((section("segmentName,sectionName,[optional]sectionType,[optional]sectionAttribute,[optional]stubSize")))
From https://opensource.apple.com/source/clang/clang-137/src/lib/MC/MCSectionMachO.cpp allowed sectionTypes
:
{ "regular", "S_REGULAR" }, // 0x00
{ 0, "S_ZEROFILL" }, // 0x01
{ "cstring_literals", "S_CSTRING_LITERALS" }, // 0x02
{ "4byte_literals", "S_4BYTE_LITERALS" }, // 0x03
{ "8byte_literals", "S_8BYTE_LITERALS" }, // 0x04
{ "literal_pointers", "S_LITERAL_POINTERS" }, // 0x05
{ "non_lazy_symbol_pointers", "S_NON_LAZY_SYMBOL_POINTERS" }, // 0x06
{ "lazy_symbol_pointers", "S_LAZY_SYMBOL_POINTERS" }, // 0x07
{ "symbol_stubs", "S_SYMBOL_STUBS" }, // 0x08
{ "mod_init_funcs", "S_MOD_INIT_FUNC_POINTERS" }, // 0x09
{ "mod_term_funcs", "S_MOD_TERM_FUNC_POINTERS" }, // 0x0A
{ "coalesced", "S_COALESCED" }, // 0x0B
{ 0, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C
{ "interposing", "S_INTERPOSING" }, // 0x0D
{ "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E
{ 0, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F
{ 0, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10
{ "thread_local_regular", "S_THREAD_LOCAL_REGULAR" }, // 0x11
{ "thread_local_zerofill", "S_THREAD_LOCAL_ZEROFILL" }, // 0x12
{ "thread_local_variables", "S_THREAD_LOCAL_VARIABLES" }, // 0x13
{ "thread_local_variable_pointers",
"S_THREAD_LOCAL_VARIABLE_POINTERS" }, // 0x14
{ "thread_local_init_function_pointers",
"S_THREAD_LOCAL_INIT_FUNCTION_POINTERS"}, // 0x15
Allowed section attributes
:
ENTRY("pure_instructions", S_ATTR_PURE_INSTRUCTIONS)
ENTRY("no_toc", S_ATTR_NO_TOC)
ENTRY("strip_static_syms", S_ATTR_STRIP_STATIC_SYMS)
ENTRY("no_dead_strip", S_ATTR_NO_DEAD_STRIP)
ENTRY("live_support", S_ATTR_LIVE_SUPPORT)
ENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE)
ENTRY("debug", S_ATTR_DEBUG)
ENTRY("" /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
ENTRY("" /*FIXME*/, S_ATTR_EXT_RELOC)
ENTRY("" /*FIXME*/, S_ATTR_LOC_RELOC)
Some examples:
//Variable in brand new segment & section, segment VM access defaults to read/write
int intInCustomPlace __attribute__ ( (section ("__DATA2,__data2") ));
//Read only string constant outside of __TEXT in readonly __LINKEDIT
char *kString __attribute__ ( (section ("__LINKEDIT,__customSection") )) = "value";
//C function in custom segment & section
void foo() __attribute__ ( (section ("__TEXT_EXEC,__customSection") ));
//obj-c method in custom section
- (void) foo:(NSInteger)someArg __attribute__ ( (section ("__TEXT, __customSection") ));
Bear in mind you can easily break stuff, MachOView
is a convenient tool for inspecting your binary. Custom ("__TEXT,__cstring")
replacement would be most likely your best shot.
EDIT: A nonexisting segment by default will be emitted as readable & writeable (just like __DATA
) so this won't work for executable code.
If you want explore the inline assembly path it's documented here: https://developer.apple.com/library/content/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html
回答2:
ld
's -rename_section
flag does the job.
来源:https://stackoverflow.com/questions/47896174/how-can-i-sections-out-of-text-and-into-a-new-segment-for-a-mach-o-binary