[lld-macho] Add support for objc_msgSend stubs
Apple Clang in Xcode 14 introduced a new feature for reducing the
overhead of objc_msgSend calls by deduplicating the setup calls for each
individual selector. This works by clang adding undefined symbols for
each selector called in a translation unit, such as _objc_msgSend$foo
for calling the foo method on any NSObject. There are 2
different modes for this behavior, the default directly does the setup
for _objc_msgSend and calls it, and the smaller option does the
selector setup, and then calls the standard _objc_msgSend stub
function.
The general overview of how this works is:
- Undefined symbols with the given prefix are collected
- The suffix of each matching undefined symbol is added as a string to __objc_methname
- A pointer is added for every method name in the __objc_selrefs section
- A got entry is emitted for _objc_msgSend
- Stubs are emitting pointing to the synthesized locations
Notes:
- Both __objc_methname and __objc_selrefs can also exist from object files, so their contents are merged with our synthesized contents
- The compiler emits method names for defined methods, but not for undefined symbols you call, but stubs are used for both
- This only implements the default "fast" mode currently just to reduce the diff, I also doubt many folks will care to swap modes
- This only implements this for arm64 and x86_64, we don't need to implement this for 32 bit iOS archs, but we should implement it for watchOS archs in a later diff
What's the purpose of these brk #0 instructions? Also, any idea why they are rendered as brk #0x1 in the arm64-objcstubs.s test?