Run-time Dynamic type-casting (RTTI), contd

Sry, I'd like to answer to Run-time Dynamic type-casting (RTTI) - #25 by andreytkachenko, but that topic has been closed, hope you don't mind me creating a new one.

I tried to map the vtable to symbol name (using dladdr), but looks like there is no corresponding symbol (but dli_fname is not NULL and points to the executable name):

use std::mem;
use libc::{dladdr, Dl_info};

struct AStruct;

trait Foo {}
impl Foo for AStruct {}

trait Bar {}
impl Bar for AStruct {}

unsafe fn f(x: &dyn Foo) {
	let (_, vtbl): (*const (), *const ()) = mem::transmute(x);

	let mut dli: Dl_info = mem::zeroed();
	let ret = dladdr(vtbl as *const libc::c_void, &mut dli);
	if ret == 0 { return; }

	println!("{:?} {:?}", dli.dli_fname, dli.dli_sname); // dli.dli_sname is 0x0 :'(
}

fn main() {
	unsafe { f(&AStruct{}); }
}

You prolly got the idea: extract the type name from the symbol, and try to lookup the vtable corresponding to the type name and some other trait name.

Using strings for the executable file, I could find strings mentioning AStruct and/or Foo vtable, but nm shows only symbols for f and main. So it seems the vtable names are not exported. Am I right?

Correct, vtables are anonymous constants whose symbol names start with .L in the object files, which causes the linker to strip them. In any case you get symbol names like .Lanon.fad58de7366495db4650cfefac2fcd61.0 where the long string is not guaranteed to be identical for two vtables of the same trait/type combination, nor guaranteed to be unique between two trait/type combinations in different codegen units.

I once looked at giving vtables names — not for any feature, just to get more helpful assembly listings — and found that this is literally true: creation of the vtable goes through the same paths that allocate static memory for a constant value of any type. So, adding names for vtables would require either splitting that out or adding the ability to pass a symbol name through the static allocation system.