Unable to correctly find class rodata

I'm trying to use some of the data in a class's rodata to look at the class's objc mangled name, but it seems that the rodata structure I get is incorrect.

I'm doing the following to try and retrieve it:

struct ClassMetadata {
  let metaclass: UnsafePointer<ClassMetaclass>
  let superclass: Any.Type?
  let reserved: (Int, Int)
  let rodata: Int
}

struct ClassMetaclass {
  let superclass0: Any.Type?
  let superclass1: Any.Type?
  let reserved: (Int, Int)
  let metaclassData: UnsafeRawPointer
}

struct ROData {
  let flags: UInt32
  let instanceStart: UInt32
  let instanceSize: UInt32
  let reserved: UInt32
  let ivarLayout: UnsafeRawPointer
  let name: UnsafePointer<CChar>
  let methodList: UnsafeRawPointer
  let protocolList: UnsafeRawPointer
  let ivarList: UnsafeRawPointer
  let weakIvarLayout: UnsafeRawPointer
  let propertyList: UnsafeRawPointer
}

func printObjCMangledName(for type: AnyObject.Type) {
  let metadata = unsafeBitCast(
    type,
    to: UnsafePointer<ClassMetadata>.self
  ).pointee

  // We're assuming a target who's using Swift in the OS.
  let rodataAddress = metadata.rodata & ~0x2
  let rodata = UnsafePointer<ROData>(
    bitPattern: rodataAddress
  )!.pointee

  print(String(cString: rodata.name))
}

When I look at other fields of the metadata they're correct (the superclasses all register as SwiftObject), but the rodata just doesn't seem correct because the name that get's printed is not what's being emitted (-emit-assembly). Is the ObjC runtime altering some of these values? (I don't know much about ObjC, so I don't know if it changes any of the emitted data structures the Swift compiler emits.)

The rodata pointer gets replaced by rwdata when a class is realized, and rwdata layout is private to the Objective-C runtime, so you should use the Objective-C runtime API to ask questions about it. In newer Apple OSes, many parts of the ObjC metadata are instantiated lazily for Swift classes, including the runtime name.

1 Like

Thanks Joe, that explains it!

Aside: Thanks for answering all of my weird questions!

2 Likes