private void ReflectClassEnum(Class cls, IDiaSymbol member_symbol) { if (cls.MinimalReflection) { return; } string full_type_name = cls.FullName.String + "::" + member_symbol.name; // Merge already existing unnamed enumerations Rfl.Type enum_type = null; if (member_symbol.name != "<unnamed-tag>" || m_TypeMap.TryGetValue(full_type_name, out enum_type) == false) { enum_type = new Rfl.Enum( cls, member_symbol.name, (uint)member_symbol.length, TypeOfVirtualAddress("enum " + full_type_name)); m_TypeMap.Add(full_type_name, enum_type); m_DiaSymbolMap.Add(enum_type, member_symbol); cls.Enums.Add(enum_type as Rfl.Enum); } LoadEnumEntries(enum_type as Rfl.Enum, member_symbol); }
private void LoadEnumEntries(Rfl.Enum type, IDiaSymbol dia_type) { IDiaEnumSymbols enum_entries; dia_type.findChildren(SymTagEnum.SymTagData, null, 0, out enum_entries); m_Logger.WriteSection("Reflecting Enum - {" + type.FullName.String + "}"); foreach (IDiaSymbol symbol in enum_entries) { // The values of an enumeration are stored as the smallest type possible (sbyte, short, int) // so need casting to int (casting to uint gives out of range exceptions). int value = System.Convert.ToInt32(symbol.value); type.AddEntry(symbol.name, value); m_Logger.Write(symbol.name + " = " + value.ToString()); } m_Logger.EndSection(); }
private void LoadReflectedTypes(Module module) { // Look for all overloaded implementations of the registration function IDiaEnumSymbols enum_symbols; m_Session.globalScope.findChildren(SymTagEnum.SymTagFunction, "RflReflectedTypesTable", 0, out enum_symbols); foreach (IDiaSymbol symbol in enum_symbols) { // Get the first argument IDiaEnumSymbols enum_args; symbol.findChildren(SymTagEnum.SymTagData, "arg", 0, out enum_args); IDiaSymbol arg = enum_args.Item(0); // Get base type information IDiaSymbol dia_type = arg.type.type; string type_name = GetTypeName(dia_type); string full_type_name = type_name; uint size = (uint)dia_type.length; Namespace cur_ns = module.GlobalNamespace.FindOrCreateNamespace(ref type_name); Rfl.Type type = null; // Is a template being reflected? symbol.findChildren(SymTagEnum.SymTagData, "is_template", 0, out enum_args); if (enum_args.count != 0) { // Strip the template parameters type_name = type_name.Remove(type_name.IndexOf('<')); full_type_name = full_type_name.Remove(full_type_name.IndexOf('<')); Rfl.Template template = new Rfl.Template(cur_ns, type_name); cur_ns.Templates.Add(template); type = template; m_Logger.WriteSection("Reflect Request Template - {" + template.FullName.String + "}"); } else { switch ((SymTagEnum)dia_type.symTag) { case SymTagEnum.SymTagBaseType: { Rfl.BaseType base_type = new Rfl.BaseType( cur_ns, type_name, size, TypeOfVirtualAddress(full_type_name)); m_Logger.WriteSection("Reflect Request BaseType - {" + base_type.FullName.String + "}"); cur_ns.BaseTypes.Add(base_type); type = base_type; break; } case SymTagEnum.SymTagUDT: { Rfl.Class class_type = new Rfl.Class( cur_ns, type_name, size, TypeOfVirtualAddress(full_type_name), dia_type.constructor == 0); m_Logger.WriteSection("Reflect Request Class - {" + class_type.FullName.String + "}"); cur_ns.Classes.Add(class_type); type = class_type; break; } case SymTagEnum.SymTagEnum: { Rfl.Enum enum_type = new Rfl.Enum( cur_ns, type_name, size, TypeOfVirtualAddress("enum " + full_type_name)); m_Logger.WriteSection("Reflect Request Enum - {" + enum_type.FullName.String + "}"); cur_ns.Enums.Add(enum_type); LoadEnumEntries(enum_type, dia_type); type = enum_type; break; } default: m_Logger.WriteError("Can not reflect unknown type - {" + type_name + "}"); continue; } } // Check for light-weight type reflection symbol.findChildren(SymTagEnum.SymTagData, "minimal", 0, out enum_args); if (enum_args.count != 0) { type.MinimalReflection = true; m_Logger.Write("Minimal Reflection"); } m_TypeMap.Add(full_type_name, type); m_DiaSymbolMap.Add(type, dia_type); m_Logger.EndSection(); } }