what does the $ld$add$os10.4$ prefix mean when I use nm to look at a symbol list on a Mac?

╄→尐↘猪︶ㄣ 提交于 2019-12-22 20:09:08

问题


I'm having some problems with my iPhone app not linking for the iPhone Simulator. It tells me there are undefined symbols:

Undefined symbols for architecture i386:
  ".objc_class_name_NSRunLoop", referenced from:
      pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
  ".objc_class_name_NSDate", referenced from:
      pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
  ".objc_class_name_NSAutoreleasePool", referenced from:
      pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
      pointer-to-literal-objc-class-name in libRenderSystem_GLES2Static.a(OgreEAGL2Window.mm.o)
  ".objc_class_name_UIApplication", referenced from:
      pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
      pointer-to-literal-objc-class-name in libOIS.a(iPhoneInputManager.mm.o)
  ".objc_class_name_NSObject", referenced from:
      .objc_class_name_AppDelegate in SampleBrowser.cpp.o
  ".objc_class_name_UIView", referenced from:
      .objc_class_name_SampleBrowserGestureView in SampleBrowser.cpp.o
      .objc_class_name_InputDelegate in libOIS.a(iPhoneInputManager.mm.o)
      .objc_class_name_EAGL2View in libRenderSystem_GLES2Static.a(OgreEAGL2View.mm.o)
  ".objc_class_name_UIScreen", referenced from:
      pointer-to-literal-objc-class-name in libOIS.a(iPhoneInputManager.mm.o)
      pointer-to-literal-objc-class-name in libRenderSystem_GLES2Static.a(OgreEAGL2Support.mm.o)
  ".objc_class_name_UIAccelerometer", referenced from:
      pointer-to-literal-objc-class-name in libOIS.a(iPhoneInputManager.mm.o)
      pointer-to-literal-objc-class-name in libOIS.a(iPhoneAccelerometer.mm.o)

But these looks like the names of Objective-C classes from frameworks which I AM linking against. I wanted to do some digging around so I used nm to look at the symbol list of the frameworks I'm linking against. For instance

josh$ nm /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/Foundation.framework/Foundation -arch i386 -g | grep objc_class
001a4500 S $ld$add$os10.4$.objc_class_name_NSArray
001a4501 S $ld$add$os10.4$.objc_class_name_NSCalendar
001a4502 S $ld$add$os10.4$.objc_class_name_NSData
001a4503 S $ld$add$os10.4$.objc_class_name_NSDate
001a4504 S $ld$add$os10.4$.objc_class_name_NSDateComponents
001a4505 S $ld$add$os10.4$.objc_class_name_NSDictionary
001a4506 S $ld$add$os10.4$.objc_class_name_NSEnumerator
001a4507 S $ld$add$os10.4$.objc_class_name_NSException
001a4508 S $ld$add$os10.4$.objc_class_name_NSInputStream
001a4509 S $ld$add$os10.4$.objc_class_name_NSInvocation
001a450a S $ld$add$os10.4$.objc_class_name_NSLocale
001a450b S $ld$add$os10.4$.objc_class_name_NSMethodSignature
001a450c S $ld$add$os10.4$.objc_class_name_NSMutableArray
001a450d S $ld$add$os10.4$.objc_class_name_NSMutableData
001a450e S $ld$add$os10.4$.objc_class_name_NSMutableDictionary
001a450f S $ld$add$os10.4$.objc_class_name_NSMutableSet
001a4510 S $ld$add$os10.4$.objc_class_name_NSNull
001a4511 S $ld$add$os10.4$.objc_class_name_NSObject
001a4512 S $ld$add$os10.4$.objc_class_name_NSOutputStream
001a4513 S $ld$add$os10.4$.objc_class_name_NSRunLoop
001a4514 S $ld$add$os10.4$.objc_class_name_NSSet
001a4515 S $ld$add$os10.4$.objc_class_name_NSStream
001a4516 S $ld$add$os10.4$.objc_class_name_NSTimeZone
001a4517 S $ld$add$os10.4$.objc_class_name_NSTimer
001a4548 S $ld$add$os10.4$.objc_class_name_NSURL
001a4518 S $ld$add$os10.4$.objc_class_name_NSUserDefaults
001a4549 S $ld$add$os10.5$.objc_class_name_NSURL
001a454a S $ld$hide$os10.4$.objc_class_name_NSFileWrapper
001a454b S $ld$hide$os10.5$.objc_class_name_NSFileWrapper
001a454c S $ld$hide$os10.6$.objc_class_name_NSFileWrapper

Now, this symbol list makes it look to me like that framework archive IS exporting the classes that the linker is looking for. The only thing that's different is this $ld$add$os10.4$ prefix. I'm wondering why it's there, what it means, and is that, perhaps, causing my problem?

Edit: Looks like this was my problem: Link errors in Xcode when targeting iPhoneSimulator

In short, leaving off the compiler flag -fobjc-abi-version=2 leads to the different symbol naming.


回答1:


$ld$add$osXX.X$SYMBOL is a linker directive that allows one to redirect symbol resolution in a library. The command sits in the __DATA section of a binary and is parsed by ld at link time to change the visibility of exported symbols. The linker on OS X actually accepts quite a few different kinds of these commands:

$ld$hide$osXX.X$SYMBOL Adds that symbol to the ignore set. The Linker will no longer export that symbol to any binaries that link with the library even though it may have global visibility.

$ld$add$osXX.X$SYMBOL Adds that symbol to the binary at link time regardless of whether a definition exists.

$ld$install_name$osXX.X Redirects the definition of a symbol in a particular binary to another binary. This is used to work around an issue in OS X where CoreGraphics used to exist as a sub-framework of ApplicationServices. All symbols are now redirected around to the proper framework.

$ld$compatibility_version Forces compatibility with earlier versions of the Linker.

In your case, you've bumped up against a compatibility issue in Foundation. OS X exported NSFileWrapper in AppKit until 10.7 when the symbol was hidden from there and moved to Foundation. Normally, this means the author of AppKit would hide the _OBJC_CLASS_$, _OBJC_METACLASS_$, and _OBJC_IVAR_$ parts of a class definition to make the linker look elsewhere for that symbol. However, because you removed the -fobjc-abi-version flag the compiler defaults back to the old 1.x ABI which only requires the hiding and finding of a .objc_class_name which probably don't exist in the binary you're trying to link.

As for your undefined symbols, it's a simple file extension issue. .cpp are c++ only files, (which means no NSRunloop, MSMutableArray, NSObject, etc). If you wish to access these objects, rename the offending files with the extension .mm, which is a standard objC++ file. It's also a good idea to link against and import QuartzCore (for EAGL2View) and UIKit (for UIScreen and friends along with UIAccelerometer).




回答2:


I'm not really clued up on the iOS SDK, but why are you compiling for "i386"?. I ran into this similar problem a few nights ago while playing with PhoneGap. I just removed "i386" from my XCode project settings and everything seemed to work fine in the simulator after that. Though i could be wrong.



来源:https://stackoverflow.com/questions/10134189/what-does-the-ldaddos10-4-prefix-mean-when-i-use-nm-to-look-at-a-symbol-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!