Linker changes in Xcode 16 / macOS 15?

I have existing code in production that links against the mach-o library, and uses the following code:

NSData *data = [NSData dataWithBytes: getsectiondata(&_mh_execute_header, "__TEXT", "__somePlist_plist", &len) length:len];

In order for this to compile with Sequoia Beta 4 and Xcode 16 beta 4, I have to replace _mh_execute_header with _mh_dylib_header.

If I don't, the compiler raises the following error: ld: Undefined symbols: __mh_execute_header, referenced from: -[MyClass init] in MyClass.o clang: error: linker command failed with exit code 1 (use -v to see invocation)

Any idea why the linking behavior might have changed? Should I file a bug?

(I realize this is a C issue, not Objective-C - but didn't find a tag for that)

Thanks!

Answered by DTS Engineer in 799146022

So, lemme break this down by language:

  • Swift

  • Objective-C

In Swift you can use #dsohandle to get the start of the Mach-O image regardless of the image type, so this problem goes away. Well, you’ll need to combine that with an unsafeBitCast(_:to:).

In C-based languages things are not that simple (when are they ever :-). I asked around internally and got an excellent tip: Use __dso_handle as a ‘universal’ Mach-O image start symbol. The only tricky thing is that you have to declare it yourself:

extern const struct mach_header __dso_handle; 

Please take this for a spin and let me know if you hit any roadblocks.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I have a similar issue, but I think the __dso_handle trick is not fixing it for me.
I have a framework that needs to find a section in the main app binary.
Until now I could use this (simplified) code to achieve this:

uint8_t* get_slided_section_data(const char* seg, const char* sect, size_t* size) {
  uint8_t* data = nullptr;
  for (unsigned i = 0, n = _dyld_image_count(); i < n && !data; i++) {
    const mach_header* header = _dyld_get_image_header(i);
    if (header->filetype == MH_EXECUTE) {
      data = getsectiondata((mach_header_64*)header, seg, sect, size);
    }
  }
  return data;
}

However, this seems to not work anymore (I assume the same reason as the original issue).

From my understanding, __dso_handle points only to the defining image image start. Since I need to find a section from a framework in the main app binary, this seems not to work.

Is there some way to make this work/achieve the same thing with ENABLE_DEBUG_DYLIB enabled?

Linker changes in Xcode 16 / macOS 15?
 
 
Q