private NavObjectModel NewObject(string line, ObjectSection objectSection) { string[] parts = line.Split(' '); if (objectSection != ObjectSection.Object) { return(null); } if (parts.Length == 0) { return(null); } if (parts[0] != "OBJECT") { return(null); } return(new NavObjectModel() { Type = parts[1], Id = ObjectHelper.GetInt(parts[2]), Name = ObjectHelper.GetObjectName(line) }); }
public override bool Visit(ObjectSection node) { traverse(node.fields); traverse(node.decls); return(true); }
private void SetObjectProperties(string line, ObjectSection objectSection, ref NavObjectModel navObject) { if (objectSection != ObjectSection.ObjectProperties) { return; } string[] parts = line.Split('='); switch (ObjectHelper.RemoveIllChar(parts[0])) { case "Date": navObject.StringDate = ObjectHelper.RemoveIllChar(parts[1]); break; case "Time": navObject.StringTime = ObjectHelper.RemoveIllChar(parts[1]); break; case "Modified": navObject.Modified = ObjectHelper.GetBool(parts[1]); break; case "Version List": navObject.VersionList = ObjectHelper.GetVersionList(line, parts[0]); break; } }
public override bool Visit(ObjectSection node) { traverse(node.fields); // do not print Visit((Section)node); traverse(node.properties); // do not print return(true); }
public MprObjGrd(string id_rpt_obj, ObjectSection s) { ID = null; IDReport = id_rpt_obj; Name = "Grid" + DateTime.Now.ToLongTimeString(); Category = ObjectCategory.Grid; Section = s; Index = 0; Printed = true; Type = ObjectType.Static; RotateAngle = 0; Rows = ""; RowsSQL = ""; Width = 1000; Location = new Point(0, 0); RowHeight = 70; ColumnHeaderHeight = 90; ColumnFooterHeight = 90; ColumnHeaderPrinted = true; ColumnFooterPrinted = true; Columns = new Collection<MprObjGrdCol>(); TextStyle = new MprStlTxt(); BoxStyle = new MprStlRect(); }
internal void Read(EndianBinaryReader reader, ObjectSection section = null) { uint signature = reader.ReadUInt32(); reader.SeekCurrent(4); // Unused flags int meshCount, materialCount; long meshesOffset, materialsOffset; // X stores mesh/material count before the bounding sphere if (section?.Format == BinaryFormat.X) { meshCount = reader.ReadInt32(); materialCount = reader.ReadInt32(); BoundingSphere = reader.ReadBoundingSphere(); meshesOffset = reader.ReadOffset(); materialsOffset = reader.ReadOffset(); reader.SkipNulls(4 * sizeof(uint)); Flags = reader.ReadUInt32(); // TODO: Is this available in other games? reader.SkipNulls(sizeof(uint)); } else { BoundingSphere = reader.ReadBoundingSphere(); meshCount = reader.ReadInt32(); meshesOffset = reader.ReadOffset(); materialCount = reader.ReadInt32(); materialsOffset = reader.ReadOffset(); } reader.SkipNulls(10 * sizeof(uint)); Meshes.Capacity = meshCount; for (int i = 0; i < meshCount; i++) { reader.ReadAtOffset(meshesOffset + i * Mesh.GetByteSize(section?.Format ?? BinaryFormat.DT), () => { var mesh = new Mesh(); mesh.Read(reader, section); Meshes.Add(mesh); }); } Materials.Capacity = materialCount; for (int i = 0; i < materialCount; i++) { reader.ReadAtOffset(materialsOffset + i * Material.BYTE_SIZE, () => { var material = new Material(); material.Read(reader); Materials.Add(material); }); } }
private NavObjectModel CreateNewObject(string line, ObjectSection objectSection, NavObjectModel navObject) { NavObjectModel newNavObject = NewObject(line, objectSection); if (newNavObject != null) { navObject = newNavObject; _navObjects.Add(newNavObject.InternalId, newNavObject); } return(navObject); }
protected void Given_Section(string name, SectionHeaderType type, uint flags, byte[] blob) { var os = new ObjectSection { Name = name, Type = type, Flags = flags, Content = blob, }; objectSections.Add(os); }
public MprObjRect(string id_rpt_obj, ObjectSection s) { ID = null; IDReport = id_rpt_obj; Name = "Rectangle" + DateTime.Now.ToLongTimeString(); Category = ObjectCategory.Rectangle; Section = s; Index = 0; Printed = true; Type = ObjectType.Static; RotateAngle = 0; Location = new Point(0, 0); Size = new System.Drawing.Size(500, 70); Style = new MprStlRect(); }
public MprObjLine(string id_rpt_obj, ObjectSection s) { ID = null; IDReport = id_rpt_obj; Name = "Line" + DateTime.Now.ToLongTimeString(); Category = ObjectCategory.Line; Section = s; Index = 0; Printed = true; Type = ObjectType.Static; RotateAngle = 0; Point1 = new Point(0, 0); Point2 = new Point(500, 100); Style = new MprStlPen(); }
internal void Write(EndianBinaryWriter writer, ObjectSection section = null) { writer.Write(0x10000); writer.Write(0); if (section?.Format == BinaryFormat.X) { writer.Write(Meshes.Count); writer.Write(Materials.Count); writer.Write(BoundingSphere); writer.ScheduleWriteOffset(8, AlignmentMode.Left, WriteMeshes); writer.ScheduleWriteOffset(8, AlignmentMode.Left, WriteMaterials); writer.WriteNulls(4 * sizeof(uint)); writer.Write(Flags); writer.WriteNulls(sizeof(uint)); } else { writer.Write(BoundingSphere); writer.Write(Meshes.Count); writer.ScheduleWriteOffset(8, AlignmentMode.Left, WriteMeshes); writer.Write(Materials.Count); writer.ScheduleWriteOffset(8, AlignmentMode.Left, WriteMaterials); } writer.WriteNulls(10 * sizeof(uint)); void WriteMeshes() { foreach (var mesh in Meshes) { mesh.Write(writer, section); } } void WriteMaterials() { foreach (var material in Materials) { material.Write(writer); } } }
public MprObjImgFld(string id_rpt_obj, ObjectSection s) { ID = null; IDReport = id_rpt_obj; Name = "ImageField" + DateTime.Now.ToLongTimeString(); Category = ObjectCategory.ImageField; Section = s; Index = 0; Printed = true; SizeMode = ImageSizeMode.Stretch; Type = ObjectType.Static; RotateAngle = 0; Location = new Point(0, 0); Size = new System.Drawing.Size(250, 250); Image = null; ImageFile = ""; ImageSQL = ""; Style = new MprStlRect(); }
private void ProcessLine(string line, ObjectSection objectSection, ref NavObjectModel navObject) { switch (objectSection) { case ObjectSection.Object: navObject = CreateNewObject(line, objectSection, navObject); break; case ObjectSection.ObjectProperties: SetObjectProperties(line, objectSection, ref navObject); navObject.ObjectProperties.Add(line); break; default: if (navObject != null) { navObject.Code.Add(line); } break; //case ObjectSection.Properties: // navObject.Properties.Add(line); // break; //case ObjectSection.Fields: // navObject.Fields.Add(line); // break; //case ObjectSection.Keys: // navObject.Keys.Add(line); // break; //case ObjectSection.FieldGroups: // navObject.FieldGroups.Add(line); // break; //case ObjectSection.Code: // navObject.Code.Add(line); // break; } if (navObject != null) { navObject.ObjectLines.Add(line); } }
internal void Write(EndianBinaryWriter writer, ObjectSection section = null) { writer.Write(0); writer.Write(BoundingSphere); writer.Write(MaterialIndex); if (MaterialUVIndices?.Length == 8) { writer.Write(MaterialUVIndices); } else { writer.WriteNulls(8); } writer.Write(BoneIndices != null ? BoneIndices.Length : 0); writer.ScheduleWriteOffsetIf(BoneIndices != null, 4, AlignmentMode.Left, () => { writer.Write(BoneIndices); }); writer.Write(BoneIndices != null ? 4 : 0); writer.Write(( int )PrimitiveType); writer.Write(1); writer.Write(Indices.Length); // Modern Format if (section != null) { writer.Write(( uint )section.IndexData.AddIndices(Indices)); writer.WriteNulls(section.Format == BinaryFormat.X ? 24 : 20); writer.Write(BoundingBox); writer.Write(Field00); writer.Write(0); } else { writer.ScheduleWriteOffset(4, AlignmentMode.Left, () => { writer.Write(Indices); }); writer.WriteNulls(32); } }
internal void Read(EndianBinaryReader reader, ObjectSection section = null) { reader.SeekCurrent(4); BoundingSphere = reader.ReadBoundingSphere(); MaterialIndex = reader.ReadInt32(); MaterialUVIndices = reader.ReadBytes(8); int boneIndexCount = reader.ReadInt32(); long boneIndicesOffset = reader.ReadOffset(); uint field00 = reader.ReadUInt32(); PrimitiveType = ( PrimitiveType )reader.ReadUInt32(); int field01 = reader.ReadInt32(); int indexCount = reader.ReadInt32(); uint indicesOffset = reader.ReadUInt32(); if (section != null) { reader.SeekCurrent(section.Format == BinaryFormat.X ? 0x18 : 0x14); BoundingBox = reader.ReadBoundingBox(); Field00 = reader.ReadInt32(); } else { BoundingBox = BoundingSphere.ToBoundingBox(); } reader.ReadAtOffsetIf(field00 == 4, boneIndicesOffset, () => { BoneIndices = reader.ReadUInt16s(boneIndexCount); }); if (section == null) { reader.ReadAtOffset(indicesOffset, () => { Indices = reader.ReadUInt16s(indexCount); }); } else { var indexReader = section.IndexData.Reader; indexReader.SeekBegin(section.IndexData.DataOffset + indicesOffset); Indices = indexReader.ReadUInt16s(indexCount); } }
public MprObjTxtFld(string id_rpt_obj, ObjectSection s) { ID = null; IDReport = id_rpt_obj; Name = "TextField" + DateTime.Now.ToLongTimeString(); Category = ObjectCategory.TextField; Section = s; Index = 0; Printed = true; Type = ObjectType.Static; RotateAngle = 0; Text = "TextField" + DateTime.Now.ToLongTimeString(); TextSQL = ""; Location = new Point(0, 0); Size = new System.Drawing.Size(500, 70); TextStyle = new MprStlTxt(); Shape = ObjectShape.Rectangle; RectangleStyle = new MprStlRect(); EllipseStyle = new MprStlEllp(); }
public void RunImportFromObjectFile(string filePath) { if (string.IsNullOrEmpty(filePath)) { return; } if (!File.Exists(filePath)) { return; } if (!IsTxtFile(filePath)) { return; } ObjectSection currObjectSection = ObjectSection.Unknown; NavObjectModel currNavObject = null; var lines = File.ReadAllLines(filePath, Encoding.Default); int totalLineCount = lines.Length; for (int i = 0; i < totalLineCount; i++) { ObjectSection objectSection = ObjectHelper.FindObjectSection(lines[i]); if (objectSection != ObjectSection.Unknown) { currObjectSection = objectSection; } ProcessLine(lines[i], currObjectSection, ref currNavObject); // FireFileReadEvent(i, totalLineCount); } }
public virtual T Visit(ObjectSection node) { Visit((Section)node); return(traverse(node.fields)); }
private static retType AISSectionLoad( AISGen devAISGen, ObjectFile file, ObjectSection section) { Byte[] secData = file.secRead(section); Byte[] srcCRCData = new Byte[section.size + 8]; Debug.DebugMSG("AISSectionLoad for section " + section.name + " from file " + file.FileName + "."); // If we are doing section-by-section CRC, then zero out the CRC value if (devAISGen.aisCRCType == AisCRCCheckType.SECTION_CRC) { devAISGen.devCRC.ResetCRC(); } // Add section load to the output devAISGen.InsertAISSectionLoad((UInt32) section.loadAddr, (UInt32) section.size, secData); // Copy bytes to CRC byte array for future CRC calculation if (devAISGen.aisCRCType != AisCRCCheckType.NO_CRC) { if (devAISGen.devEndian != devAISGen.devAISEndian) { Endian.swapEndian(BitConverter.GetBytes(section.loadAddr)).CopyTo(srcCRCData, 0); Endian.swapEndian(BitConverter.GetBytes(section.size)).CopyTo(srcCRCData, 4); } else { BitConverter.GetBytes(section.loadAddr).CopyTo(srcCRCData, 0); BitConverter.GetBytes(section.size).CopyTo(srcCRCData, 4); } } // Now write contents to CRC array for (UInt32 k = 0; k < section.size; k+=4) { // Copy bytes to array for future CRC calculation if (devAISGen.aisCRCType != AisCRCCheckType.NO_CRC) { Byte[] temp = new Byte[4]; Array.Copy(secData,k,temp,0,4); if (devAISGen.devEndian != devAISGen.devAISEndian) { Endian.swapEndian(temp).CopyTo(srcCRCData, (8 + k)); } else { temp.CopyTo(srcCRCData, (8 + k)); } } } // Add this section's memory range, checking for overlap AddMemoryRange(devAISGen, (UInt32) section.loadAddr, (UInt32) (section.loadAddr+section.size-1)); // Perform CRC calculation of the section's contents if (devAISGen.aisCRCType != AisCRCCheckType.NO_CRC) { devAISGen.devCRC.CalculateCRC(srcCRCData); if (devAISGen.aisCRCType == AisCRCCheckType.SECTION_CRC) { // Write CRC request command, value, and jump value to temp AIS file devAISGen.InsertAISRequestCRC(((Int32)(-1) * (Int32)(section.size + 12 + 12))); } } return retType.SUCCESS; }
internal void Write(EndianBinaryWriter writer, ObjectSection section = null) { writer.Write(0); writer.Write(BoundingSphere); writer.Write(SubMeshes.Count); writer.ScheduleWriteOffset(8, AlignmentMode.Left, () => { foreach (var subMesh in SubMeshes) { subMesh.Write(writer, section); } }); int vertexSize = 0; VertexFormatAttributes vertexFormat = default; if (section != null) { vertexFormat = VertexFormatAttributes.UsesModernStorage; vertexSize = BoneWeights != null ? 56 : 44; } else { if (Positions != null) { vertexFormat |= VertexFormatAttributes.Position; vertexSize += 12; } if (Normals != null) { vertexFormat |= VertexFormatAttributes.Normal; vertexSize += 12; } if (Tangents != null) { vertexFormat |= VertexFormatAttributes.Tangent; vertexSize += 16; } if (TexCoords0 != null) { vertexFormat |= VertexFormatAttributes.TexCoord0; vertexSize += 8; } if (TexCoords1 != null) { vertexFormat |= VertexFormatAttributes.TexCoord1; vertexSize += 8; } if (TexCoords2 != null) { vertexFormat |= VertexFormatAttributes.TexCoord2; vertexSize += 8; } if (TexCoords3 != null) { vertexFormat |= VertexFormatAttributes.TexCoord3; vertexSize += 8; } if (Colors0 != null) { vertexFormat |= VertexFormatAttributes.Color0; vertexSize += 16; } if (Colors1 != null) { vertexFormat |= VertexFormatAttributes.Color1; vertexSize += 16; } if (BoneWeights != null) { vertexFormat |= VertexFormatAttributes.BoneWeight | VertexFormatAttributes.BoneIndex; vertexSize += 32; } } writer.Write(( int )vertexFormat); writer.Write(vertexSize); writer.Write(Positions.Length); if (section != null) { WriteVertexAttributesModern(); } else { WriteVertexAttributesClassic(); } writer.Write(( int )Flags); writer.Write(section != null ? (BoneWeights != null ? 4 : 2) : 0); writer.WriteNulls(6 * sizeof(uint)); // Reserved writer.Write(Name, StringBinaryFormat.FixedLength, 64); void WriteVertexAttributesClassic() { for (int i = 0; i < 20; i++) { var attribute = ( VertexFormatAttributes )(1 << i); writer.ScheduleWriteOffsetIf((vertexFormat & attribute) != 0, ( int )attribute + 1, 4, AlignmentMode.Left, () => { switch (attribute) { case VertexFormatAttributes.Position: writer.Write(Positions); break; case VertexFormatAttributes.Normal: writer.Write(Normals); break; case VertexFormatAttributes.Tangent: writer.Write(Tangents); break; case VertexFormatAttributes.TexCoord0: writer.Write(TexCoords0); break; case VertexFormatAttributes.TexCoord1: writer.Write(TexCoords1); break; case VertexFormatAttributes.TexCoord2: writer.Write(TexCoords2); break; case VertexFormatAttributes.TexCoord3: writer.Write(TexCoords3); break; case VertexFormatAttributes.Color0: writer.Write(Colors0); break; case VertexFormatAttributes.Color1: writer.Write(Colors1); break; case VertexFormatAttributes.BoneWeight: foreach (var weight in BoneWeights) { writer.Write(weight.Weight1); writer.Write(weight.Weight2); writer.Write(weight.Weight3); writer.Write(weight.Weight4); } break; case VertexFormatAttributes.BoneIndex: foreach (var weight in BoneWeights) { writer.Write(weight.Index1 < 0 ? -1f : weight.Index1 * 3.0f); writer.Write(weight.Index2 < 0 ? -1f : weight.Index2 * 3.0f); writer.Write(weight.Index3 < 0 ? -1f : weight.Index3 * 3.0f); writer.Write(weight.Index4 < 0 ? -1f : weight.Index4 * 3.0f); } break; } }); } } void WriteVertexAttributesModern() { int byteSize = writer.AddressSpace.GetByteSize(); writer.Align(byteSize); writer.WriteNulls(13 * byteSize); writer.WriteOffset(section.VertexData.AddSubMesh(this, vertexSize)); writer.WriteNulls(6 * byteSize); } }
internal void Read(EndianBinaryReader reader, ObjectSection section = null) { reader.SeekCurrent(4); // Unused flags BoundingSphere = reader.ReadBoundingSphere(); int subMeshCount = reader.ReadInt32(); long subMeshesOffset = reader.ReadOffset(); var vertexFormat = ( VertexFormatAttributes )reader.ReadUInt32(); int vertexSize = reader.ReadInt32(); int vertexCount = reader.ReadInt32(); var attributeOffsets = reader.ReadOffsets(20); Flags = ( MeshFlags )reader.ReadInt32(); uint attributeFlags = reader.ReadUInt32(); reader.SkipNulls(6 * sizeof(uint)); Name = reader.ReadString(StringBinaryFormat.FixedLength, 64); reader.ReadAtOffset(subMeshesOffset, () => { SubMeshes.Capacity = subMeshCount; for (int i = 0; i < subMeshCount; i++) { var subMesh = new SubMesh(); subMesh.Read(reader, section); SubMeshes.Add(subMesh); } }); // Modern Format if ((vertexFormat & VertexFormatAttributes.UsesModernStorage) != 0) { ReadVertexAttributesModern(); } else { ReadVertexAttributesClassic(); } void ReadVertexAttributesClassic() { Vector4[] boneWeights = null; Vector4[] boneIndices = null; for (int i = 0; i < attributeOffsets.Length; i++) { var attribute = ( VertexFormatAttributes )(1 << i); reader.ReadAtOffsetIf((vertexFormat & attribute) != 0, attributeOffsets[i], () => { switch (attribute) { case VertexFormatAttributes.Position: Positions = reader.ReadVector3s(vertexCount); break; case VertexFormatAttributes.Normal: Normals = reader.ReadVector3s(vertexCount); break; case VertexFormatAttributes.Tangent: Tangents = reader.ReadVector4s(vertexCount); break; case VertexFormatAttributes.TexCoord0: TexCoords0 = reader.ReadVector2s(vertexCount); break; case VertexFormatAttributes.TexCoord1: TexCoords1 = reader.ReadVector2s(vertexCount); break; case VertexFormatAttributes.TexCoord2: TexCoords2 = reader.ReadVector2s(vertexCount); break; case VertexFormatAttributes.TexCoord3: TexCoords3 = reader.ReadVector2s(vertexCount); break; case VertexFormatAttributes.Color0: Colors0 = reader.ReadColors(vertexCount); break; case VertexFormatAttributes.Color1: Colors1 = reader.ReadColors(vertexCount); break; case VertexFormatAttributes.BoneWeight: boneWeights = reader.ReadVector4s(vertexCount); break; case VertexFormatAttributes.BoneIndex: boneIndices = reader.ReadVector4s(vertexCount); break; default: Console.WriteLine("Unhandled vertex format element: {0}", attribute); break; } }); } if (boneWeights == null || boneIndices == null) { return; } BoneWeights = new BoneWeight[vertexCount]; for (int i = 0; i < vertexCount; i++) { var weight4 = boneWeights[i]; var index4 = Vector4.Divide(boneIndices[i], 3); var boneWeight = new BoneWeight { Weight1 = weight4.X, Weight2 = weight4.Y, Weight3 = weight4.Z, Weight4 = weight4.W, Index1 = ( int )index4.X, Index2 = ( int )index4.Y, Index3 = ( int )index4.Z, Index4 = ( int )index4.W }; boneWeight.Validate(); BoneWeights[i] = boneWeight; } } void ReadVertexAttributesModern() { Positions = new Vector3[vertexCount]; Normals = new Vector3[vertexCount]; Tangents = new Vector4[vertexCount]; TexCoords0 = new Vector2[vertexCount]; TexCoords1 = new Vector2[vertexCount]; if (attributeFlags == 10) { TexCoords2 = new Vector2[vertexCount]; TexCoords3 = new Vector2[vertexCount]; } else if (attributeFlags == 6) { TexCoords2 = new Vector2[vertexCount]; } Colors0 = new Color[vertexCount]; if (attributeFlags == 4) { BoneWeights = new BoneWeight[vertexCount]; } bool hasTangents = false; EndianBinaryReader vertexReader; long baseOffset; if (section != null) { vertexReader = section.VertexData.Reader; baseOffset = section.VertexData.DataOffset; } else { vertexReader = reader; baseOffset = reader.BaseOffset; } long current = reader.Position; for (int i = 0; i < vertexCount; i++) { vertexReader.SeekBegin(baseOffset + attributeOffsets[13] + vertexSize * i); Positions[i] = vertexReader.ReadVector3(); Normals[i] = vertexReader.ReadVector3(VectorBinaryFormat.Int16); vertexReader.SeekCurrent(2); Tangents[i] = vertexReader.ReadVector4(VectorBinaryFormat.Int16); TexCoords0[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); TexCoords1[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); if (attributeFlags == 10) { TexCoords2[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); TexCoords3[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); } else if (attributeFlags == 6) { TexCoords2[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); } Colors0[i] = vertexReader.ReadColor(VectorBinaryFormat.Half); if (attributeFlags == 4) { var boneWeight = new BoneWeight { Weight1 = vertexReader.ReadUInt16() / 32767f, Weight2 = vertexReader.ReadUInt16() / 32767f, Weight3 = vertexReader.ReadUInt16() / 32767f, Weight4 = vertexReader.ReadUInt16() / 32767f, Index1 = vertexReader.ReadByte() / 3, Index2 = vertexReader.ReadByte() / 3, Index3 = vertexReader.ReadByte() / 3, Index4 = vertexReader.ReadByte() / 3 }; boneWeight.Validate(); BoneWeights[i] = boneWeight; } // Normalize normal because precision Normals[i] = Vector3.Normalize(Normals[i]); // Checks to get rid of useless data after reading if (Tangents[i] != Vector4.Zero) { hasTangents = true; } } if (!hasTangents) { Tangents = null; } reader.SeekBegin(current); } if (Tangents == null) { return; } for (int i = 0; i < Tangents.Length; i++) { int direction = Math.Sign(Tangents[i].W); var tangent = Vector3.Normalize(new Vector3(Tangents[i].X, Tangents[i].Y, Tangents[i].Z)); Tangents[i] = new Vector4(tangent, direction); } }
private static void writeSection(EndianBinaryWriter writer, ObjectSection section, byte[] contents) { // RPRC section contents: // u32 type; // u64 da; // u32 len; // u8 content[...] = { len bytes of binary data }; uint type = 1; // 1: TEXT, 2: DATA (TODO use both?) ulong addr = section.loadAddr; uint size = (uint)section.size; // write section to file writer.Write(type); writer.Write(addr); writer.Write(size); writer.Write(contents); }
internal void Read(EndianBinaryReader reader, ObjectSection section = null) { reader.SeekCurrent(4); // Unused flags BoundingSphere = reader.ReadBoundingSphere(); MaterialIndex = reader.ReadUInt32(); TexCoordIndices = reader.ReadBytes(8); int boneIndexCount = reader.ReadInt32(); long boneIndicesOffset = reader.ReadOffset(); BonesPerVertex = reader.ReadUInt32(); PrimitiveType = ( PrimitiveType )reader.ReadUInt32(); IndexFormat = ( IndexFormat )reader.ReadInt32(); int indexCount = reader.ReadInt32(); long indicesOffset = reader.ReadOffset(); Flags = ( SubMeshFlags )reader.ReadInt32(); if (section != null) { reader.SkipNulls(4 * sizeof(uint)); BoundingBox = reader.ReadBoundingBox(); reader.SeekCurrent(sizeof(uint)); // Max Index } else { BoundingBox = BoundingSphere.ToBoundingBox(); reader.SkipNulls(6 * sizeof(uint)); } IndexOffset = reader.ReadUInt32(); if (section?.Format == BinaryFormat.X) { reader.SeekCurrent(4); } reader.ReadAtOffsetIf(BonesPerVertex == 4, boneIndicesOffset, () => { BoneIndices = reader.ReadUInt16s(boneIndexCount); }); if (section == null) { reader.ReadAtOffset(indicesOffset, () => { ReadIndices(reader); }); } else { long current = reader.Position; { var indexReader = section.IndexData.Reader; indexReader.SeekBegin(section.IndexData.DataOffset + indicesOffset); ReadIndices(indexReader); } reader.SeekBegin(current); } void ReadIndices(EndianBinaryReader r) { Indices = new uint[indexCount]; switch (IndexFormat) { case IndexFormat.UInt8: for (int i = 0; i < Indices.Length; i++) { byte index = r.ReadByte(); Indices[i] = index == 0xFF ? 0xFFFFFFFF : index; } break; case IndexFormat.UInt16: for (int i = 0; i < Indices.Length; i++) { ushort index = r.ReadUInt16(); Indices[i] = index == 0xFFFF ? 0xFFFFFFFF : index; } break; case IndexFormat.UInt32: for (int i = 0; i < Indices.Length; i++) { Indices[i] = r.ReadUInt32(); } break; default: throw new ArgumentOutOfRangeException(); } } }
private void ParseBinaryFile(UInt64 address) { // Output console message Console.WriteLine("Parsing the input file, {0}.", fileName); // Set endian to little endian = Endian.LittleEndian; // Set section count sectionCount = 1; loadableSectionCount = 1; symbolCount = 0; binFile.Seek(0, SeekOrigin.Begin); EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); sections = new ObjectSection[sectionCount]; sections[0] = new ObjectSection(); sections[0].name = fileName; sections[0].loadAddr = address; sections[0].runAddr = address; sections[0].size = (UInt64) binFile.Length; sections[0].size = ((sections[0].size + 3) >> 2) << 2; sections[0].binFileAddr = 0x00000000; sections[0].isLoadable = true; loadableSections = new ObjectSection[loadableSectionCount]; loadableSections[0] = sections[0]; }
/// <summary> /// AIS Section Load command generation /// </summary> /// <param name="cf">The COFFfile object that the section comes from.</param> /// <param name="secHeader">The Hashtable object of the section header to load.</param> /// <param name="devAISGen">The specific device AIS generator object.</param> /// <returns>retType enumerator indicating success or failure.</returns> private static retType AISSecureSectionLoad( AISGen devAISGen, ObjectFile file, ObjectSection section, Boolean encryptSection) { Byte[] secData = file.secRead(section); // Write Section_Load AIS command, load address, and size if (encryptSection) { Byte[] encData = null; // Encrypt data using CTS algorithm try { encData = AesManagedUtil.AesCTSEncrypt(secData,devAISGen.customerEncryptionKey,devAISGen.CEKInitialValue); } catch(Exception e) { Console.WriteLine("Exception during encryption operation: {0}",e.Message); return retType.FAIL; } if (encData != null) { devAISGen.InsertAISEncSectionLoad((UInt32) section.loadAddr, (UInt32) section.size, secData, encData); } else { Console.WriteLine("Section encryption failed."); return retType.FAIL; } } else { devAISGen.InsertAISSectionLoad((UInt32) section.loadAddr, (UInt32) section.size, secData); } // Add this section's memory range, checking for overlap AddMemoryRange(devAISGen, (UInt32) section.loadAddr, (UInt32) (section.loadAddr+section.size-1)); return retType.SUCCESS; }
internal void Write(EndianBinaryWriter writer, ObjectSection section = null) { writer.Write(0); writer.Write(BoundingSphere); writer.Write(SubMeshes.Count); writer.ScheduleWriteOffset(4, AlignmentMode.Left, () => { foreach (var subMesh in SubMeshes) { subMesh.Write(writer, section); } }); int stride = 0; VertexFormatAttribute attributes = default; if (section != null) { attributes = VertexFormatAttribute.UsesModernStorage; if (BoneWeights != null) { stride = 56; } else { stride = 44; } } else { if (Vertices != null) { attributes |= VertexFormatAttribute.Vertex; stride += 12; } if (Normals != null) { attributes |= VertexFormatAttribute.Normal; stride += 12; } if (Tangents != null) { attributes |= VertexFormatAttribute.Tangent; stride += 16; } if (UVChannel1 != null) { attributes |= VertexFormatAttribute.UVChannel1; stride += 8; } if (UVChannel2 != null) { attributes |= VertexFormatAttribute.UVChannel2; stride += 8; } if (Colors != null) { attributes |= VertexFormatAttribute.Color; stride += 16; } if (BoneWeights != null) { attributes |= VertexFormatAttribute.BoneWeight | VertexFormatAttribute.BoneIndex; stride += 32; } } writer.Write(( int )attributes); writer.Write(stride); writer.Write(Vertices.Length); if (section != null) { WriteVertexAttributesModern(); } else { WriteVertexAttributesClassic(); } writer.Write(Name, StringBinaryFormat.FixedLength, 64); void WriteVertexAttributesClassic() { for (int i = 0; i < 28; i++) { var attribute = ( VertexFormatAttribute )(1 << i); writer.ScheduleWriteOffsetIf((attributes & attribute) != 0, 4, AlignmentMode.Left, () => { switch (attribute) { case VertexFormatAttribute.Vertex: writer.Write(Vertices); break; case VertexFormatAttribute.Normal: writer.Write(Normals); break; case VertexFormatAttribute.Tangent: writer.Write(Tangents); break; case VertexFormatAttribute.UVChannel1: writer.Write(UVChannel1); break; case VertexFormatAttribute.UVChannel2: writer.Write(UVChannel2); break; case VertexFormatAttribute.Color: writer.Write(Colors); break; case VertexFormatAttribute.BoneWeight: foreach (var weight in BoneWeights) { writer.Write(weight.Weight1); writer.Write(weight.Weight2); writer.Write(weight.Weight3); writer.Write(weight.Weight4); } break; case VertexFormatAttribute.BoneIndex: foreach (var weight in BoneWeights) { writer.Write(weight.Index1 < 0 ? -1f : weight.Index1 * 3.0f); writer.Write(weight.Index2 < 0 ? -1f : weight.Index2 * 3.0f); writer.Write(weight.Index3 < 0 ? -1f : weight.Index3 * 3.0f); writer.Write(weight.Index4 < 0 ? -1f : weight.Index4 * 3.0f); } break; } }); } } void WriteVertexAttributesModern() { writer.WriteNulls(section.Format == BinaryFormat.X ? 0x6C : 0x34); writer.Write(( uint )section.VertexData.AddSubMesh(this, stride)); writer.WriteNulls(section.Format == BinaryFormat.X ? 0x38 : 0x1C); writer.Write(BoneWeights != null ? 4 : 2); writer.WriteNulls(0x18); } }
void PrintSection(ObjectSection c, int yStartSection) { foreach ( DataRow rObj in Cfg.DbRpt.DataTable("SELECT " + MprTblObj.id_obj + ", " + MprTblObj.cat_obj + ", " + MprTblObj.rotate_angle_obj + ", " + MprTblObj.location_obj + " FROM " + MprTblObj.TableName + " WHERE " + MprTblObj.id_rpt_obj + "=" + Rpt.ID + " AND " + MprTblObj.section_obj + "='" + c + "' ORDER BY " + MprTblObj.index_obj).Rows ) { Point loc = UtlConvert.ToIH(UtlConvert.ToPoint(rObj[MprTblObj.location_obj].ToString())); loc.Y += yStartSection; G.TranslateTransform(loc.X, loc.Y); G.RotateTransform(int.Parse(rObj[MprTblObj.rotate_angle_obj].ToString())); switch (UtlMprVwr.ToObjectCategory(rObj[MprTblObj.cat_obj].ToString())) { case ObjectCategory.TextField: PrintObjTxtFld(rObj[MprTblObj.id_obj].ToString()); break; case ObjectCategory.ImageField: PrintObjImgFld(rObj[MprTblObj.id_obj].ToString()); break; case ObjectCategory.Line: PrintObjLine(rObj[MprTblObj.id_obj].ToString()); break; case ObjectCategory.Rectangle: PrintObjRect(rObj[MprTblObj.id_obj].ToString()); break; case ObjectCategory.Ellipse: PrintObjEllp(rObj[MprTblObj.id_obj].ToString()); break; case ObjectCategory.Grid: PrintObjGrid(rObj[MprTblObj.id_obj].ToString()); break; default: break; } G.RotateTransform(-int.Parse(rObj[MprTblObj.rotate_angle_obj].ToString())); G.TranslateTransform(-loc.X, -loc.Y); } }
/// <summary> /// Parse the section headers. /// </summary> private void ParseSectionHdrs() { UInt32 numBytesInSectionHdr; EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); if (hdr.c_version == COFF_Version.COFF2) { numBytesInSectionHdr = 48; } else if (hdr.c_version == COFF_Version.COFF1) { numBytesInSectionHdr = 40; } else { numBytesInSectionHdr = 0; } sectionRef = new Hashtable[sectionCount]; sections = new ObjectSection[sectionCount]; for (UInt16 secNum = 0; secNum < sectionCount; secNum++) { sectionRef[secNum] = new Hashtable(); sections[secNum] = new ObjectSection(); ebr.BaseStream.Seek(numBytesInSectionHdr * secNum + COFFHeaderSize + hdr.c_ehsize, SeekOrigin.Begin); sections[secNum].name = COFF_getName(); ebr.BaseStream.Seek(numBytesInSectionHdr * secNum + COFFHeaderSize + hdr.c_ehsize + 8, SeekOrigin.Begin); sections[secNum].runAddr = (UInt64) ebr.ReadUInt32(); sections[secNum].loadAddr = (UInt64) ebr.ReadUInt32(); sections[secNum].size = (UInt64) ebr.ReadUInt32(); sections[secNum].size = ((sections[secNum].size + 3) >> 2) << 2; sections[secNum].binFileAddr = (UInt64) ebr.ReadUInt32(); sectionRef[secNum]["reloPtr"] = ebr.ReadUInt32(); sectionRef[secNum]["linePtr"] = ebr.ReadUInt32(); if (hdr.c_version == COFF_Version.COFF2) { sectionRef[secNum].Add("numRelos", ebr.ReadUInt32()); sectionRef[secNum].Add("numLines", ebr.ReadUInt32()); sectionRef[secNum].Add("flags", ebr.ReadUInt32()); sectionRef[secNum].Add("reserved", (UInt32) ebr.ReadUInt16()); sectionRef[secNum].Add("memPage", (UInt32) ebr.ReadUInt16()); } else { sectionRef[secNum].Add("numRelos", (UInt32) ebr.ReadUInt16()); sectionRef[secNum].Add("numLines", (UInt32) ebr.ReadUInt16()); sectionRef[secNum].Add("flags", (UInt32) ebr.ReadUInt16()); sectionRef[secNum].Add("reserved", (UInt32) ebr.ReadByte()); sectionRef[secNum].Add("memPage", (UInt32) ebr.ReadByte()); } //Check to see if section is bootable UInt32 flags = (UInt32)sectionRef[secNum]["flags"]; sectionRef[secNum]["bootable"] = false; if ((flags & ((UInt32)(COFF_SectionType.TEXT | COFF_SectionType.DATA))) != 0) { if ((flags & ((UInt32)COFF_SectionType.COPY)) == 0) { if (sections[secNum].size != 0) { headerRef["numBootSections"] = ((UInt32)headerRef["numBootSections"]) + 1; sectionRef[secNum]["bootable"] = true; } } } // Check to see if section is loadable sections[secNum].isLoadable = false; if ( ( sections[secNum].binFileAddr != 0 ) && ( sections[secNum].size != 0 ) ) { if ((flags & ((UInt32)(COFF_SectionType.BSS | // No BSS sections COFF_SectionType.COPY | // No COPY sections COFF_SectionType.NOLOAD | // No NOLOAD sections COFF_SectionType.DUMMY)) // No DUMMY sections ) == 0) { sections[secNum].isLoadable = true; loadableSectionCount++; } } Debug.DebugMSG("ObjectSection sections[" + secNum + "] = \n{"); Debug.DebugMSG("\tname = " + sections[secNum].name + ","); Debug.DebugMSG("\tsize = " + sections[secNum].size.ToString("X8") + ","); Debug.DebugMSG("\trunAddr = " + sections[secNum].runAddr.ToString("X8") + ","); Debug.DebugMSG("\tloadAddr = " + sections[secNum].loadAddr.ToString("X8") + ","); Debug.DebugMSG("\tisLoadable = " + sections[secNum].isLoadable + ","); Debug.DebugMSG("\tbinFileAddr = " + sections[secNum].binFileAddr.ToString("X8")); Debug.DebugMSG("}"); } // Fill in the loadableSections array loadableSections = new ObjectSection[loadableSectionCount]; for (UInt32 secNum = 0,loadableSecNum=0; secNum < sectionCount; secNum++) { if (sections[secNum].isLoadable) { loadableSections[loadableSecNum] = sections[secNum]; loadableSecNum++; } } // Finally, sort the loadable sections array by load address Array.Sort<ObjectSection>(loadableSections); Debug.DebugMSG("Parse Section Headers Done"); }
internal void Write(EndianBinaryWriter writer, ObjectSection section = null) { writer.Write(0); writer.Write(BoundingSphere); writer.Write(MaterialIndex); if (TexCoordIndices?.Length == 8) { writer.Write(TexCoordIndices); } else { writer.WriteNulls(8); } writer.Write(BoneIndices?.Length ?? 0); writer.ScheduleWriteOffsetIf(BoneIndices != null, 4, AlignmentMode.Left, () => { writer.Write(BoneIndices); }); writer.Write(BonesPerVertex); writer.Write(( int )PrimitiveType); writer.Write(( int )IndexFormat); writer.Write(Indices.Length); // Modern Format if (section != null) { writer.WriteOffset(section.IndexData.AddSubMesh(this)); writer.Write(( int )Flags); writer.WriteNulls(4 * sizeof(uint)); writer.Write(BoundingBox); switch (IndexFormat) { case IndexFormat.UInt8: writer.WriteNulls(3); writer.Write(( byte )Indices.Max()); break; case IndexFormat.UInt16: writer.WriteNulls(2); writer.Write(( ushort )Indices.Max()); break; case IndexFormat.UInt32: writer.Write(Indices.Max()); break; default: throw new ArgumentOutOfRangeException(); } } else { writer.ScheduleWriteOffset(8, AlignmentMode.Left, () => { switch (IndexFormat) { case IndexFormat.UInt8: foreach (uint index in Indices) { writer.Write(( byte )index); } break; case IndexFormat.UInt16: foreach (uint index in Indices) { writer.Write(( ushort )index); } break; case IndexFormat.UInt32: foreach (uint index in Indices) { writer.Write(index); } break; default: throw new ArgumentOutOfRangeException(); } }); writer.Write(( int )Flags); writer.WriteNulls(6 * sizeof(uint)); } writer.Write(IndexOffset); if (section?.Format == BinaryFormat.X) { writer.WriteNulls(sizeof(uint)); } }
public override bool Visit(ObjectSection node) { Visit((Section)node); TraverseSetParent(node, node.fields); return(true); }
private static bool sectionOverlap(ObjectSection section, ObjectSection[] externSections) { // note: s1, s2 are the beginning and end locations of this section in memory ulong s1 = section.loadAddr, s2 = section.loadAddr + section.size - 1, x1, x2; foreach (ObjectSection exSection in externSections) { // note: x1, x2 are the beginning and end locations of the external section in memory x1 = exSection.loadAddr; x2 = exSection.loadAddr + exSection.size - 1; // sections collide if any of the following is true: // 1) s1 is inside the external section // 2) s2 is inside the external section // 3) s1 is before the external section and s2 is after it if ((s1 >= x1 && s1 <= x2) || (s2 >= x1 && s2 <= x2) || (s1 < x1 && s2 > x2)) return true; } return false; }
/// <summary> /// Checks if current context is inside an object (method usually). /// If given an argument, checks if this ObjectSection is the defining scope /// </summary> public bool IsContextInObject(ObjectSection sec = null) { var osec = GetDeclaringObjectSection(); return(sec != null && !ReferenceEquals(osec, sec)); }
internal void Read(EndianBinaryReader reader, ObjectSection section = null) { reader.SeekCurrent(4); BoundingSphere = reader.ReadBoundingSphere(); int subMeshCount = reader.ReadInt32(); long subMeshesOffset = reader.ReadOffset(); var attributes = ( VertexFormatAttribute )reader.ReadUInt32(); int stride = reader.ReadInt32(); int vertexCount = reader.ReadInt32(); var elemItems = reader.ReadUInt32s(section?.Format == BinaryFormat.X ? 49 : 28); Name = reader.ReadString(StringBinaryFormat.FixedLength, 64); SubMeshes.Capacity = subMeshCount; for (int i = 0; i < subMeshCount; i++) { reader.ReadAtOffset(subMeshesOffset + i * SubMesh.GetByteSize(section?.Format ?? BinaryFormat.DT), () => { var subMesh = new SubMesh(); subMesh.Read(reader, section); SubMeshes.Add(subMesh); }); } // Modern Format if (section != null) { ReadVertexAttributesModern(); } else { ReadVertexAttributesClassic(); } void ReadVertexAttributesClassic() { Vector4[] boneWeights = null; Vector4[] boneIndices = null; for (int i = 0; i < 28; i++) { var attribute = ( VertexFormatAttribute )(1 << i); reader.ReadAtOffsetIf((attributes & attribute) != 0, elemItems[i], () => { switch (attribute) { case VertexFormatAttribute.Vertex: Vertices = reader.ReadVector3s(vertexCount); break; case VertexFormatAttribute.Normal: Normals = reader.ReadVector3s(vertexCount); break; case VertexFormatAttribute.Tangent: Tangents = reader.ReadVector4s(vertexCount); break; case VertexFormatAttribute.UVChannel1: UVChannel1 = reader.ReadVector2s(vertexCount); break; case VertexFormatAttribute.UVChannel2: UVChannel2 = reader.ReadVector2s(vertexCount); break; case VertexFormatAttribute.Color: Colors = reader.ReadColors(vertexCount); break; case VertexFormatAttribute.BoneWeight: boneWeights = reader.ReadVector4s(vertexCount); break; case VertexFormatAttribute.BoneIndex: boneIndices = reader.ReadVector4s(vertexCount); break; default: Console.WriteLine("Unhandled vertex format element: {0}", attribute); break; } }); } if (boneWeights != null && boneIndices != null) { BoneWeights = new BoneWeight[vertexCount]; for (int i = 0; i < vertexCount; i++) { var weight4 = boneWeights[i]; var index4 = Vector4.Divide(boneIndices[i], 3); var boneWeight = new BoneWeight { Weight1 = weight4.X, Weight2 = weight4.Y, Weight3 = weight4.Z, Weight4 = weight4.W, Index1 = ( int )index4.X, Index2 = ( int )index4.Y, Index3 = ( int )index4.Z, Index4 = ( int )index4.W }; boneWeight.Validate(); BoneWeights[i] = boneWeight; } } } void ReadVertexAttributesModern() { uint dataOffset = elemItems[section.Format == BinaryFormat.X ? 27 : 13]; uint attributeFlags = elemItems[section.Format == BinaryFormat.X ? 42 : 21]; if (attributeFlags == 2 || attributeFlags == 4) { Vertices = new Vector3[vertexCount]; Normals = new Vector3[vertexCount]; Tangents = new Vector4[vertexCount]; UVChannel1 = new Vector2[vertexCount]; UVChannel2 = new Vector2[vertexCount]; Colors = new Color[vertexCount]; if (attributeFlags == 4) { BoneWeights = new BoneWeight[vertexCount]; } bool hasTangents = false; bool hasUVChannel2 = false; bool hasColors = false; var vertexReader = section.VertexData.Reader; for (int i = 0; i < vertexCount; i++) { vertexReader.SeekBegin(section.VertexData.DataOffset + dataOffset + stride * i); Vertices[i] = vertexReader.ReadVector3(); Normals[i] = vertexReader.ReadVector3(VectorBinaryFormat.Int16); vertexReader.SeekCurrent(2); Tangents[i] = vertexReader.ReadVector4(VectorBinaryFormat.Int16); UVChannel1[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); UVChannel2[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half); Colors[i] = vertexReader.ReadColor(VectorBinaryFormat.Half); if (attributeFlags == 4) { var boneWeight = new BoneWeight { Weight1 = vertexReader.ReadUInt16() / 32767f, Weight2 = vertexReader.ReadUInt16() / 32767f, Weight3 = vertexReader.ReadUInt16() / 32767f, Weight4 = vertexReader.ReadUInt16() / 32767f, Index1 = vertexReader.ReadByte() / 3, Index2 = vertexReader.ReadByte() / 3, Index3 = vertexReader.ReadByte() / 3, Index4 = vertexReader.ReadByte() / 3 }; boneWeight.Validate(); BoneWeights[i] = boneWeight; } // Normalize normal because precision Normals[i] = Vector3.Normalize(Normals[i]); // Checks to get rid of useless data after reading if (Tangents[i] != Vector4.Zero) { hasTangents = true; } if (UVChannel1[i] != UVChannel2[i]) { hasUVChannel2 = true; } if (!Colors[i].Equals(Color.White)) { hasColors = true; } } if (!hasTangents) { Tangents = null; } if (!hasUVChannel2) { UVChannel2 = null; } if (!hasColors) { Colors = null; } } if (Tangents != null) { for (int i = 0; i < Tangents.Length; i++) { int direction = Math.Sign(Tangents[i].W); var tangent = Vector3.Normalize(new Vector3(Tangents[i].X, Tangents[i].Y, Tangents[i].Z)); Tangents[i] = new Vector4(tangent, direction); } } } }
/// <summary> /// Parse the section headers. /// </summary> private void ParseSectionHdrs() { UInt32 byteSize, wordSize, numBytesInSectionHdr; UInt64 flags; ELF_SectionHeader secHdr; EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); numBytesInSectionHdr = hdr.e_shentsize; Debug.DebugMSG("Parsing ELF Sections Headers"); if (sectionCount == (UInt32) ELF_SectionIndex.SHN_UNDEF) { // Get the actual number of sections from the sh_size field of the // 0th section header table entry secHdr = ReadSectionHeader(0); sectionCount = (UInt32) secHdr.sh_size; headerRef["numSectionHdrs"] = (UInt32) secHdr.sh_size; } // Get Section Header String Table Section Header Index and Section Header String Table Section Address if (hdr.e_shstrndx == (UInt16) ELF_SectionIndex.SHN_UNDEF) { headerRef["stringTableAddr"] = null; headerRef["stringHeaderTableIndex"] = null; secHdr = new ELF_SectionHeader(); } else if (hdr.e_shstrndx == (UInt16) ELF_SectionIndex.SHN_XINDEX) { secHdr = ReadSectionHeader(0); headerRef["stringHeaderTableIndex"] = (UInt32) secHdr.sh_link; secHdr = ReadSectionHeader((UInt32) headerRef["stringHeaderTableIndex"]); headerRef["stringTableAddr"] = (UInt64) secHdr.sh_addr; } else { headerRef["stringHeaderTableIndex"] = (UInt32) hdr.e_shstrndx; secHdr = ReadSectionHeader((UInt32) headerRef["stringHeaderTableIndex"]); headerRef["stringTableAddr"] = (UInt64) (secHdr.sh_offset); } Debug.DebugMSG("Section Header Table Index for Section Header String Table: " + (UInt32)headerRef["stringHeaderTableIndex"]); Debug.DebugMSG("String Section Start Addr: 0x" + ((UInt64)headerRef["stringTableAddr"]).ToString("X8")); // Verify that the section header string table section is flagged as a string section flags = (UInt64) secHdr.sh_flags; Debug.DebugMSG("secHdr.sh_flags = " + secHdr.sh_flags.ToString()); if ( ( flags & ((UInt64) ELF_SectionFlag.SHF_STRINGS) ) == 0 ) { Debug.DebugMSG("WARNING: Section Header String Section is not flagged with SHF_STRINGS"); } if (secHdr.sh_type != ELF_SectionType.SHT_STRTAB) { throw new Exception("Section Header String Section is not of type SHT_STRTAB."); } if ( hdr.e_phnum == 0x0) { throw new Exception("Load addresses cannot be calculated without program header."); } // Cycle through all sections, collecting info about each (name, type, etc.) sectionRef = new Hashtable[sectionCount]; sections = new ObjectSection[sectionCount]; for (UInt32 secNum = 0; secNum < sectionCount; secNum++) { sectionRef[secNum] = new Hashtable(); sections[secNum] = new ObjectSection(); secHdr = ReadSectionHeader((UInt32) secNum); ebr.BaseStream.Seek((Int64)(secHdr.sh_name + (UInt64)headerRef["stringTableAddr"]), SeekOrigin.Begin); sectionRef[secNum]["name"] = ELF_getStringFromStringTable(); sectionRef[secNum]["type"] = (ELF_SectionType) secHdr.sh_type; sectionRef[secNum]["phyAddr"] = (UInt64) secHdr.sh_addr; sectionRef[secNum]["virAddr"] = (UInt64) secHdr.sh_addr; sectionRef[secNum]["fileAddr"] = (UInt64) secHdr.sh_offset; byteSize = (UInt32) secHdr.sh_size; wordSize = (byteSize + 3) >> 2; byteSize = wordSize << 2; sectionRef[secNum]["byteSize"] = byteSize; sectionRef[secNum]["wordSize"] = wordSize; sectionRef[secNum]["flags"] = (UInt64) secHdr.sh_flags; flags = (UInt64) sectionRef[secNum]["flags"]; // FIXME: Check to see if section should be copied to target sectionRef[secNum]["copyToTarget"] = false; if ( ( ((UInt64) sectionRef[secNum]["phyAddr"]) != 0 ) && ( ((UInt32) sectionRef[secNum]["byteSize"]) != 0 ) && ( ELF_SectionType.SHT_NULL != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_NOBITS != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_SYMTAB != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_DYNSYM != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_STRTAB != (ELF_SectionType)sectionRef[secNum]["type"] ) ) { if ( ( ELF_SectionType.SHT_PROGBITS == (ELF_SectionType)sectionRef[secNum]["type"] ) && ( (flags | ((UInt64) ELF_SectionFlag.SHF_ALLOC)) != 0x0 ) ) { headerRef["numTargetSections"] = ((UInt32)headerRef["numTargetSections"]) + 1; sectionRef[secNum]["copyToTarget"] = true; } } // If we think this section should be copied to target, make sure it is // in a loadable ELF program segment. If it is, then update physical // and virtual addresses. If not, then mark it as such. if ((Boolean) sectionRef[secNum]["copyToTarget"]) { Boolean segmentFoundForSection = false; for (UInt32 segmentNum = 0; segmentNum < (UInt32)hdr.e_phnum; segmentNum++) { ELF_SegmentHeader segmentHdr = ReadSegmentHeader((UInt32) segmentNum); // If the segment is of load type, check to see if the current section resides in it if (segmentHdr.p_type == ELF_SegmentType.PT_LOAD) { // Check if data is in the file, and if so then check if the section // is within this current segment if ( ( segmentHdr.p_filesz != 0 ) && ( segmentHdr.p_vaddr <= (UInt64) secHdr.sh_addr) && ( (segmentHdr.p_vaddr + segmentHdr.p_filesz) > (UInt64) secHdr.sh_addr) && ( segmentHdr.p_offset <= (UInt64) secHdr.sh_offset) && ( (segmentHdr.p_offset + segmentHdr.p_filesz) > (UInt64) secHdr.sh_offset) ) { sectionRef[secNum]["phyAddr"] = (UInt64) segmentHdr.p_paddr + ( secHdr.sh_addr - segmentHdr.p_vaddr); segmentFoundForSection = true; } } } if (!segmentFoundForSection) { // This section is not actually in a loadable ELF program segment, indicate that sectionRef[secNum]["copyToTarget"] = false; } } sections[secNum].name = (String) sectionRef[secNum]["name"]; sections[secNum].size = (UInt32) sectionRef[secNum]["byteSize"]; sections[secNum].runAddr = (UInt64) sectionRef[secNum]["virAddr"]; sections[secNum].loadAddr = (UInt64) sectionRef[secNum]["phyAddr"]; sections[secNum].isLoadable = (Boolean) sectionRef[secNum]["copyToTarget"]; if (sections[secNum].isLoadable) { loadableSectionCount++; } sections[secNum].binFileAddr = (UInt64) sectionRef[secNum]["fileAddr"]; Debug.DebugMSG("ObjectSection sections[" + secNum + "] = \n{"); Debug.DebugMSG("\tname = " + sections[secNum].name + ","); Debug.DebugMSG("\tsize = " + sections[secNum].size.ToString("X8") + ","); Debug.DebugMSG("\trunAddr = " + sections[secNum].runAddr.ToString("X8") + ","); Debug.DebugMSG("\tloadAddr = " + sections[secNum].loadAddr.ToString("X8") + ","); Debug.DebugMSG("\tisLoadable = " + sections[secNum].isLoadable + ","); Debug.DebugMSG("\tbinFileAddr = " + sections[secNum].binFileAddr.ToString("X8")); Debug.DebugMSG("}"); } // Fill in the loadableSections array loadableSections = new ObjectSection[loadableSectionCount]; for (UInt32 secNum = 0,loadableSecNum=0; secNum < sectionCount; secNum++) { if (sections[secNum].isLoadable) { loadableSections[loadableSecNum] = sections[secNum]; loadableSecNum++; } } // Finally, sort the loadable sections array by load address Array.Sort<ObjectSection>(loadableSections); Debug.DebugMSG("Parse Section Headers Done"); }