private LinkerSymbol CreateCustomAttributeArgument(string symbolName, int count, string name, MosaCustomAttribute.Argument arg, bool isField) { string nameForSymbol = (name == null) ? count.ToString() : name; nameForSymbol = symbolName + ":" + nameForSymbol; var symbol = Linker.CreateSymbol(nameForSymbol + Metadata.CustomAttributeArgument, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(symbol.Stream, Architecture.Endianness); // 1. Pointer to name (if named) if (name != null) { var nameSymbol = EmitStringWithLength(nameForSymbol + Metadata.NameString, name); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, (int)writer1.Position, 0, nameSymbol, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Is Argument A Field writer1.Write(isField, TypeLayout.NativePointerSize); // 3. Argument Type Pointer Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, (int)writer1.Position, 0, arg.Type.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 4. Argument Size writer1.Write(ComputeArgumentSize(arg.Type, arg.Value), TypeLayout.NativePointerSize); // 5. Argument Value WriteArgument(writer1, symbol, arg.Type, arg.Value); // Return symbol for linker usage return symbol; }
private LinkerSymbol CreateCustomAttribute(MosaUnit unit, MosaCustomAttribute ca, int position) { // Emit custom attribute list string name = unit.FullName + ">>" + position.ToString() + ":" + ca.Constructor.DeclaringType.Name; var customAttributeSymbol = Linker.CreateSymbol(name + Metadata.CustomAttribute, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(customAttributeSymbol.Stream, Architecture.Endianness); // 1. Pointer to Attribute Type Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, (int)writer1.Position, 0, ca.Constructor.DeclaringType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Constructor Method Definition Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, (int)writer1.Position, 0, ca.Constructor.FullName + Metadata.MethodDefinition, SectionKind.ROData, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Number of Arguments (Both unnamed and named) writer1.Write((uint)(ca.Arguments.Length + ca.NamedArguments.Length), TypeLayout.NativePointerSize); // 4. Pointers to Custom Attribute Arguments (Both unnamed and named) for (int i = 0; i < ca.Arguments.Length; i++) { // Build definition var customAttributeArgumentSymbol = CreateCustomAttributeArgument(name, i, null, ca.Arguments[i], false); // Link Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, (int)writer1.Position, 0, customAttributeArgumentSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); } foreach (var namedArg in ca.NamedArguments) { // Build definition var customAttributeArgumentSymbol = CreateCustomAttributeArgument(name, 0, namedArg.Name, namedArg.Argument, namedArg.IsField); // Link Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, (int)writer1.Position, 0, customAttributeArgumentSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); } // Return customAttributeSymbol for linker usage return customAttributeSymbol; }