/// <summary> /// Parse the COFF file's symbol table. /// </summary> private void ParseSymbolTable() { EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); Int64 currSymbolTableEntryFileAddr = symbolTableFileAddr; symRef = new Hashtable[symbolCount]; symbols = new ObjectSymbol[symbolCount]; Debug.DebugMSG("Begin parsing symbol table. Symbol Count = " + symbolCount + ".\n"); // Read the symbol table for (UInt32 symNum = 0; symNum < symbolCount; symNum++) { symRef[symNum] = new Hashtable(); symbols[symNum] = new ObjectSymbol(); Debug.DebugMSG("symbols[" + symNum + "] = \n{"); ebr.BaseStream.Seek( (UInt32)currSymbolTableEntryFileAddr, SeekOrigin.Begin); symbols[symNum].name = COFF_getName(); Debug.DebugMSG("\tname = " + symbols[symNum].name); ebr.BaseStream.Seek( (UInt32)currSymbolTableEntryFileAddr + 8, SeekOrigin.Begin); symbols[symNum].value = (UInt64) ebr.ReadUInt32(); Debug.DebugMSG("\tvalue = " + symbols[symNum].value.ToString("X8") + ","); symRef[symNum]["secNum"] = (Int32) ebr.ReadInt16(); symRef[symNum]["type"] = (UInt32) ebr.ReadUInt16(); symRef[symNum]["class"] = (UInt32) ebr.ReadByte(); symRef[symNum]["auxNum"] = (UInt32) ebr.ReadByte(); Debug.DebugMSG("\tsecNum = " + ((Int32)symRef[symNum]["secNum"]).ToString()); Debug.DebugMSG("\ttype = " + ((UInt32)symRef[symNum]["type"]).ToString("X4")); Debug.DebugMSG("\tclass = " + ((UInt32)symRef[symNum]["class"]).ToString()); Debug.DebugMSG("\tauxNum = " + ((UInt32)symRef[symNum]["auxNum"]).ToString("X2")); // Check to make sure auxNum is either 0 or 1 if ((((UInt32)symRef[symNum]["auxNum"]) != 0) && (((UInt32)symRef[symNum]["auxNum"]) != 1)) { throw new Exception("Invalid auxNum (" + ((UInt32)symRef[symNum]["auxNum"]) + ") detected for symbol " + symbols[symNum].name + "."); } if (((UInt32)symRef[symNum]["auxNum"]) != 0) { currSymbolTableEntryFileAddr += 2*symbolTableEntrySize; symNum++; symRef[symNum] = null; symbols[symNum] = new ObjectSymbol(); symbols[symNum].name = ""; symbols[symNum].value = symbols[symNum-1].value; Debug.DebugMSG("\tsectionLength = " + (UInt32) ebr.ReadInt32()); Debug.DebugMSG("\tnumRelocEntries = " + (UInt32) ebr.ReadUInt16()); Debug.DebugMSG("\tnumLineNumberntries = " + (UInt32) ebr.ReadUInt16()); } else { currSymbolTableEntryFileAddr += symbolTableEntrySize; } Debug.DebugMSG("}"); } // Finally, sort the symbols by value (address) Array.Sort<ObjectSymbol>(symbols); Debug.DebugMSG("Parse Symbol Table Done"); }
private ObjectInfo GenerateType(ObjectSymbol os, TokenPosition position) { var typeName = _resolver.GetAssetFullName(os); var builder = _module.DefineType(typeName, TypeAttributes.Public); builder.AddInterfaceImplementation(typeof(ITsInstance)); ObjectInfo parent = null; FieldInfo members; if (os.Inherits != null) { parent = GetObjectInfo(os.Inherits, position); builder.SetParent(parent.Type); // Todo: Verify that the parent is valid. // It shouldn't be possible to inherit from a type that // has a sealed TryGetDelegate method. } else { builder.SetParent(typeof(TsInstance)); } if (parent != null && !typeof(TsInstance).IsAssignableFrom(parent.Type)) { if (parent.Members is null) { //Todo: Memoize the result if it's not found. var inherits = parent.Type; while (inherits is TypeBuilder parentBuilder && !parentBuilder.IsCreated()) { inherits = inherits.BaseType; } members = inherits.GetField("_members", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); parent.Members = members; } else { members = parent.Members; } if (members == null || members.FieldType != typeof(Dictionary <string, TsObject>)) { members = builder.DefineField("_members", typeof(Dictionary <string, TsObject>), FieldAttributes.Family); } } else { members = _baseMemberField; } var scripts = builder.DefineField("_scripts", typeof(Dictionary <string, TsDelegate>), FieldAttributes.Private | FieldAttributes.Static); var tryGetDelegate = GenerateTryGetDelegate(builder, members, scripts, GetTryGetDelegate(parent)); var constructor = builder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.HasThis, new[] { typeof(TsObject[]) }); GenerateObjectType(builder); var info = new ObjectInfo(builder, parent?.Type ?? _baseType, tryGetDelegate, constructor, members, scripts); _definedTypes.Add(os, info); return(info); }
private void ParseSymbolTable() { EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); UInt32 numSymbols = (UInt32) headerRef["numEntriesInSymTable"]; ELF_Symbol sym; Byte info, other; symRef = new Hashtable[symbolCount]; symbols = new ObjectSymbol[symbolCount]; // Read the symbol table for (UInt32 symNum = 0; symNum < symbolCount; symNum++) { symRef[symNum] = new Hashtable(); symbols[symNum] = new ObjectSymbol(); // Go to current symbol ebr.BaseStream.Seek((Int64) ((UInt64)headerRef["symbolTableAddr"]) + ((UInt32)headerRef["symbolTableEntrySize"] * symNum),SeekOrigin.Begin); sym.st_name = (UInt32) ebr.ReadUInt32(); if (ELF_FileClass.ELFCLASS_32 == hdr.e_ident.fileClass) { sym.st_value = (UInt64) ebr.ReadUInt32(); sym.st_size = (UInt64) ebr.ReadUInt32(); info = ebr.ReadByte(); other = ebr.ReadByte(); sym.st_shndx = ebr.ReadUInt16(); } else { info = ebr.ReadByte(); other = ebr.ReadByte(); sym.st_shndx = ebr.ReadUInt16(); sym.st_value = ebr.ReadUInt64(); sym.st_size = ebr.ReadUInt64(); } sym.st_type = (ELF_SymbolType) (info & 0xF); sym.st_binding = (ELF_SymbolBinding) ((info >> 4) & 0xF); sym.st_visibility = (ELF_SymbolVisibility) (other & 0x3); /* Debug.DebugMSG( "Symbol[" + symNum + "] = \n{" ); Debug.DebugMSG( " Symbol Name Offset : 0x" + sym.st_name.ToString("X8")); Debug.DebugMSG( " Symbol Value : 0x" + sym.st_value.ToString("X16")); Debug.DebugMSG( " Symbol Size : 0x" + sym.st_size.ToString("X16")); Debug.DebugMSG( " Symbol Type : " + sym.st_type); Debug.DebugMSG( " Symbol Binding : " + sym.st_binding); Debug.DebugMSG( " Symbol Visibility : " + sym.st_visibility); Debug.DebugMSG( " Symbol's Relevant Section : 0x" + sym.st_shndx.ToString("X4")); Debug.DebugMSG( "}\n"); */ // Move to name in String Table ebr.BaseStream.Seek( (Int64) ((UInt64)headerRef["stringTableAddr"]) + (sym.st_name), SeekOrigin.Begin); symRef[symNum]["name"] = ELF_getStringFromStringTable(); symRef[symNum]["value"] = sym.st_value; symRef[symNum]["secNum"] = sym.st_shndx; symRef[symNum]["type"] = sym.st_type; symRef[symNum]["binding"] = sym.st_binding; symRef[symNum]["visibility"] = sym.st_visibility; symbols[symNum].name = (String) symRef[symNum]["name"]; symbols[symNum].value = (UInt64) symRef[symNum]["value"]; Debug.DebugMSG("symbols[" + symNum + "] = {"); Debug.DebugMSG("\tname = " + symbols[symNum].name + ","); Debug.DebugMSG("\tvalue = " + symbols[symNum].value.ToString("X8") + " }"); /* Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"name\"]: " + ((String)symRef[symNum]["name"]).ToString()); Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"value\"]: " + ((UInt64)symRef[symNum]["value"]).ToString("X8")); Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"secNum\"]: " + ((UInt16)symRef[symNum]["secNum"]).ToString("X4")); Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"type\"]: " + sym.st_type); Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"binding\"]: " + sym.st_binding); Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"visibility\"]: " + sym.st_visibility); */ } // Finally, sort the symbols by value (address) Array.Sort<ObjectSymbol>(symbols); Debug.DebugMSG("Parse Symbol Table Done"); }