public ResolvedReference ResolveTypeReference(ObjectImage context, JavaScriptObject typeReference) { JavaScriptObject metadata = context.GetMetadata(); int assemblyReferenceIndex = (int)(long)typeReference["Assembly"]; ObjectImage referencedObjectImage; if (assemblyReferenceIndex == -1) { referencedObjectImage = context; } else { JavaScriptObject assemblyReference = (JavaScriptObject)((JavaScriptArray)metadata["AssemblyReferences"])[assemblyReferenceIndex]; referencedObjectImage = ResolveAssemblyReference(assemblyReference); } JavaScriptObject referencedMetadata = referencedObjectImage.GetMetadata(); foreach (JavaScriptObject typeDefinition in (JavaScriptArray)referencedMetadata["Types"]) { if (TypeReferenceEquals(context, typeReference, referencedObjectImage, typeDefinition)) { int declaringTypeReferenceIndex = (int)(long)typeReference["DeclaringType"]; int declaringTypeReferenceIndex2 = (int)(long)typeDefinition["DeclaringType"]; if (declaringTypeReferenceIndex != -1 && declaringTypeReferenceIndex2 != -1) { // if both have declaring types JavaScriptObject declaringTypeReference = (JavaScriptObject)((JavaScriptArray)metadata["TypeReferences"])[declaringTypeReferenceIndex]; JavaScriptObject declaringTypeReference2 = (JavaScriptObject)((JavaScriptArray)referencedMetadata["TypeReferences"])[declaringTypeReferenceIndex2]; ResolvedReference resolvedReference = ResolveTypeReference(referencedObjectImage, declaringTypeReference2); if (!TypeReferenceEquals(context, declaringTypeReference, resolvedReference.Context, resolvedReference.Resolved)) { continue; } } else if (declaringTypeReferenceIndex != -1 || declaringTypeReferenceIndex2 != -1) { // if one has a declaring type and not the other continue; } return new ResolvedReference(referencedObjectImage, typeDefinition); } } // TODO: Resolve declaring type to get its full name throw new Exception("Could not resolve type: " + (typeReference.ContainsKey("DeclaringType") && (long)typeReference["DeclaringType"] != -1 ? typeReference["DeclaringType"] : typeReference["Namespace"]) + "." + typeReference["Name"]); }
public void Fixup(ObjectImage objectImage) { JavaScriptObject metadata = objectImage.GetMetadata(); JavaScriptArray fixups = objectImage.GetFixups(); List<KeyValuePair<uint, string>> codeSectionFixups = objectImage.CodeSectionFixups = new List<KeyValuePair<uint, string>>(); List<KeyValuePair<uint, string>> dataSectionFixups = objectImage.DataSectionFixups = new List<KeyValuePair<uint, string>>(); List<KeyValuePair<uint, string>> initSectionFixups = objectImage.InitializationSectionFixups = new List<KeyValuePair<uint, string>>(); List<KeyValuePair<uint, string>> currentSectionFixups; foreach (JavaScriptObject fixup in fixups) { FixupType fixupType = (FixupType)(long)fixup["Type"]; FixupType sectionFixupType = fixupType & (FixupType.CodeSection | FixupType.DataSection | FixupType.InitializationSection); fixupType = fixupType & ~FixupType.CodeSection; fixupType = fixupType & ~FixupType.DataSection; fixupType = fixupType & ~FixupType.InitializationSection; switch (sectionFixupType) { case FixupType.CodeSection: { currentSectionFixups = codeSectionFixups; break; } case FixupType.DataSection: { currentSectionFixups = dataSectionFixups; break; } case FixupType.InitializationSection: { currentSectionFixups = initSectionFixups; break; } default: { throw new LinkerException(); } } uint fixupOffset = (uint)(long)fixup["Offset"]; int fixupIndex = (int)(long)fixup["Index"]; string fixedUp; try { switch (fixupType) { case FixupType.MethodCodePointer: { JavaScriptObject methodReference = (JavaScriptObject)((JavaScriptArray)metadata["MethodReferences"])[fixupIndex]; ResolvedReference resolvedReference = ResolveMethodReference(objectImage, methodReference); fixedUp = (resolvedReference.Context.ModuleImageCodeStoreIndex + (long)resolvedReference.Resolved["CodeIndex"]).ToString(); break; } case FixupType.StaticFieldDataPointer: { JavaScriptObject fieldReference = (JavaScriptObject)((JavaScriptArray)metadata["FieldReferences"])[fixupIndex]; ResolvedReference resolvedReference = ResolveFieldReference(objectImage, fieldReference); fixedUp = (resolvedReference.Context.ModuleImageDataStoreIndex + (long)resolvedReference.Resolved["DataIndex"]).ToString(); break; } case FixupType.VTableDataPointer: { JavaScriptObject typeReference = (JavaScriptObject)((JavaScriptArray)metadata["TypeReferences"])[fixupIndex]; ResolvedReference resolvedReference = ResolveTypeReference(objectImage, typeReference); fixedUp = (resolvedReference.Context.ModuleImageDataStoreIndex + (long)resolvedReference.Resolved["VTableIndex"]).ToString(); break; } case FixupType.VTableSlot: { JavaScriptObject methodReference = (JavaScriptObject)((JavaScriptArray)metadata["MethodReferences"])[fixupIndex]; ResolvedReference resolvedReference = ResolveMethodReference(objectImage, methodReference); fixedUp = resolvedReference.Resolved["VTableSlot"].ToString(); break; } default: { throw new InvalidObjectFormatException(); } } } catch (Exception e) { Error("COULD NOT FIXUP: [" + fixupType.ToString() + " " + e.Message + "]. Object image is: " + objectImage); fixedUp = "COULD NOT FIXUP: [" + fixupType.ToString() + " " + e.Message + "]"; } currentSectionFixups.Add(new KeyValuePair<uint, string>(fixupOffset, fixedUp)); } }
public ResolvedReference ResolveMethodReference(ObjectImage context, JavaScriptObject methodReference) { JavaScriptObject metadata = context.GetMetadata(); int typeReferenceIndex = (int)(long)methodReference["Type"]; JavaScriptObject typeReference = (JavaScriptObject)((JavaScriptArray)metadata["TypeReferences"])[typeReferenceIndex]; ResolvedReference resolvedTypeDefinitionReference = ResolveTypeReference(context, typeReference); JavaScriptObject typeDefinition = resolvedTypeDefinitionReference.Resolved; foreach (JavaScriptObject methodDefinition in (JavaScriptArray)typeDefinition["Methods"]) { if (MethodReferenceEquals(context, methodReference, resolvedTypeDefinitionReference.Context, methodDefinition)) { return new ResolvedReference(resolvedTypeDefinitionReference.Context, methodDefinition); } } throw new Exception("Could not resolve method: " + typeReference["Namespace"] + "." + typeReference["Name"] + "::" + methodReference["Name"]); }
public ResolvedReference ResolveFieldReference(ObjectImage context, JavaScriptObject fieldReference) { JavaScriptObject metadata = context.GetMetadata(); int typeReferenceIndex = (int)(long)fieldReference["Type"]; JavaScriptObject typeReference = (JavaScriptObject)((JavaScriptArray)metadata["TypeReferences"])[typeReferenceIndex]; ResolvedReference resolvedTypeDefinitionReference = ResolveTypeReference(context, typeReference); JavaScriptObject typeDefinition = resolvedTypeDefinitionReference.Resolved; foreach (JavaScriptObject fieldDefinition in (JavaScriptArray)typeDefinition[(bool)fieldReference["IsStatic"] ? "StaticFields" : "Fields"]) { if (FieldReferenceEquals(context, fieldReference, fieldDefinition)) { return new ResolvedReference(resolvedTypeDefinitionReference.Context, fieldDefinition); } } throw new Exception("Could not resolve field: " + typeReference["Namespace"] + "." + typeReference["Name"] + "." + fieldReference["Name"]); }
public bool ParameterReferenceEquals(ObjectImage referenceContext, JavaScriptObject parameterReference, ObjectImage definitionContext, JavaScriptObject parameterDefinition) { /*if (((string)parameterReference["Name"]) != ((string)parameterDefinition["Name"])) { return false; }*/ if (((long)parameterReference["Sequence"]) != ((long)parameterDefinition["Sequence"])) { return false; } JavaScriptObject metadata = referenceContext.GetMetadata(); int typeReferenceIndex = (int)(long)parameterReference["Type"]; JavaScriptObject typeReference = (JavaScriptObject)((JavaScriptArray)metadata["TypeReferences"])[typeReferenceIndex]; ResolvedReference resolvedTypeDefinitionReference = ResolveTypeReference(referenceContext, typeReference); return TypeReferenceEquals(definitionContext, (JavaScriptObject)((JavaScriptArray)definitionContext.GetMetadata()["TypeReferences"])[(int)(long)parameterDefinition["Type"]], referenceContext, resolvedTypeDefinitionReference.Resolved); }
public bool MethodReferenceEquals(ObjectImage referenceContext, JavaScriptObject methodReference, ObjectImage definitionContext, JavaScriptObject methodDefinition) { if (((string)methodReference["Name"]) != ((string)methodDefinition["Name"])) { return false; } if (((bool)methodReference["HasThis"]) != ((bool)methodDefinition["HasThis"])) { return false; } JavaScriptArray methodReferenceParameterReferences = (JavaScriptArray)methodReference["Parameters"]; JavaScriptArray methodDefinitionParameters = (JavaScriptArray)methodDefinition["Parameters"]; if (methodReferenceParameterReferences.Count != methodDefinitionParameters.Count) { return false; } JavaScriptObject metadata = referenceContext.GetMetadata(); int i = 0; foreach (long parameterReferenceIndex in methodReferenceParameterReferences) { if (!ParameterReferenceEquals(referenceContext, (JavaScriptObject)((JavaScriptArray)metadata["ParameterReferences"])[(int)parameterReferenceIndex], definitionContext, (JavaScriptObject)methodDefinitionParameters[i++])) { return false; } } return true; }
public AssemblyName LoadObjectImage(string filepath) { ObjectImage objectImage = new ObjectImage(); XmlDocument objectFileXmlDocument = new XmlDocument(); try { objectFileXmlDocument.Load(filepath); } catch (XmlException e) { throw new LinkerException("Unable to load object image: " + filepath, e); } // TODO: Verify object file xml format XmlElement documentElement = objectFileXmlDocument.DocumentElement; XmlElement headerElement = (XmlElement)documentElement.GetElementsByTagName("Header")[0]; // load header JavaScriptObject header = (JavaScriptObject)JavaScriptConvert.DeserializeObject(((XmlCDataSection)headerElement.FirstChild).Data); objectImage.Header = header; JavaScriptObject metadata = objectImage.GetMetadata(); AssemblyName assemblyName = new AssemblyName(); JavaScriptObject assemblyNameObject = (JavaScriptObject)metadata["Name"]; assemblyName.Name = (string)assemblyNameObject["Name"]; assemblyName.Version = (string)assemblyNameObject["Version"]; assemblyName.Culture = (string)assemblyNameObject["Culture"]; objectImage.Name = assemblyName; // load code section XmlElement codeElement = (XmlElement)documentElement.GetElementsByTagName("Code")[0]; MemoryStream codeMemoryStream = new MemoryStream(); StreamWriter codeMemoryStreamWriter = new StreamWriter(codeMemoryStream); codeMemoryStreamWriter.Write(((XmlCDataSection)codeElement.FirstChild).Data); codeMemoryStreamWriter.Flush(); long codeMemoryStreamLength = codeMemoryStream.Position; codeMemoryStream.Seek(0, SeekOrigin.Begin); objectImage.CodeStream = codeMemoryStream; objectImage.CodeStreamLength = codeMemoryStreamLength; objectImage.MethodCount = (int)long.Parse(codeElement.GetAttribute("Length")); objectImage.ModuleImageCodeStoreIndex = _moduleImageCodeStoreSize; _moduleImageCodeStoreSize += objectImage.MethodCount; // load data section XmlElement dataElement = (XmlElement)documentElement.GetElementsByTagName("Data")[0]; MemoryStream dataMemoryStream = new MemoryStream(); StreamWriter dataMemoryStreamWriter = new StreamWriter(dataMemoryStream); dataMemoryStreamWriter.Write(((XmlCDataSection)dataElement.FirstChild).Data); dataMemoryStreamWriter.Flush(); long dataMemoryStreamLength = dataMemoryStream.Position; dataMemoryStream.Seek(0, SeekOrigin.Begin); objectImage.DataStream = dataMemoryStream; objectImage.DataStreamLength = dataMemoryStreamLength; objectImage.DataCount = (int)long.Parse(dataElement.GetAttribute("Length")); objectImage.ModuleImageDataStoreIndex = _moduleImageDataStoreSize; _moduleImageDataStoreSize += objectImage.DataCount; // load init section XmlElement initElement = (XmlElement)documentElement.GetElementsByTagName("Initialization")[0]; MemoryStream initMemoryStream = new MemoryStream(); StreamWriter initMemoryStreamWriter = new StreamWriter(initMemoryStream); initMemoryStreamWriter.Write(((XmlCDataSection)initElement.FirstChild).Data); initMemoryStreamWriter.Flush(); long initMemoryStreamLength = initMemoryStream.Position; initMemoryStream.Seek(0, SeekOrigin.Begin); objectImage.InitializationStream = initMemoryStream; objectImage.InitializationStreamLength = initMemoryStreamLength; _loadedObjectImages[assemblyName] = objectImage; return assemblyName; }