views:

116

answers:

3

On Mac OS X using Objective-C 2, plugin bundles can be compiled with one of three garbage collection settings:

  1. Not Supported
  2. Supported (-fobjc-gc)
  3. Required (-fobjc-gc-only)

How can one programmatically query a compiled plugin bundle to determine which of these three settings was used?

+2  A: 

It's part of the __OBJC segment but I don't know of any API that exposes it.

Garbage collected:

cristi:tmp diciu$ otool -v -o ./a.out 
./a.out:
Contents of (__DATA,__objc_classrefs) section
00000001000010b0 0x0
Contents of (__DATA,__objc_imageinfo) section
  version 0
    flags 0x6 OBJC_IMAGE_SUPPORTS_GC

Non garbage collected:

cristi:tmp diciu$ otool -v -o ./a.out 
./a.out:
Contents of (__DATA,__objc_classrefs) section
00000001000010b0 0x0
Contents of (__DATA,__objc_imageinfo) section
  version 0
    flags 0x0

The runtime does this using private functions: see *gc_enforcer* and it's use of * _objcInfoRequiresGC*

diciu
A: 

It's probably easiest to just try and load the bundle using NSBundle's -loadAndReturnError: method. If the bundle won't load due to the fact that its GC settings are different to those in your app, you'll get an NSExecutableRuntimeMismatchError.

Rob Keniger
+1  A: 

Following the answer from diciu, you can use the Mach-O API. You have to parse the segments contained in the binary file and search for the __OBJC one; the segment_command structure allows an access to the segment's flags.

You can also take a look at the ClassDump project. It has a pretty complete Mach-O parser.

Laurent Etiemble