private object ReadFieldData(CMExpLib.Layout.Field f, ulong file_offset, Elf64Reader.ElfHeader ehdr, bool read_references) { long old_pos = ehdr.r.BaseStream.Position; object ret = null; bool is_obj = false; ehdr.r.BaseStream.Seek((long)file_offset + (long)f.Offset, System.IO.SeekOrigin.Begin); if (f.ftype == CMExpLib.Layout.Field.FType.Value) { if (f.FieldType == null) { // It's an unknown field type, load it as a signed integer switch (f.Length) { case 1: ret = ehdr.r.ReadSByte(); break; case 2: ret = ehdr.r.ReadInt16(); break; case 4: ret = ehdr.r.ReadInt32(); is_obj = true; break; case 8: ret = ehdr.r.ReadInt64(); is_obj = true; break; default: ret = ehdr.r.ReadBytes(f.Length); break; } } else { if (f.FieldType == "I") { ret = ehdr.ReadPointer((ulong)ehdr.r.BaseStream.Position); is_obj = true; } else if (f.FieldType == "U") { ret = ehdr.ReadPointer((ulong)ehdr.r.BaseStream.Position); is_obj = true; } else if (f.FieldType == "I1") { ret = ehdr.r.ReadSByte(); } else if (f.FieldType == "I2") { ret = ehdr.r.ReadInt16(); } else if (f.FieldType == "I4") { ret = ehdr.r.ReadInt32(); } else if (f.FieldType == "I8") { ret = ehdr.r.ReadInt64(); } else if (f.FieldType == "U1") { ret = ehdr.r.ReadByte(); } else if (f.FieldType == "U2") { ret = ehdr.r.ReadUInt16(); } else if (f.FieldType == "U4") { ret = ehdr.r.ReadUInt32(); } else if (f.FieldType == "U8") { ret = ehdr.r.ReadUInt64(); } else if (f.FieldType == "Boolean") { if (ehdr.r.ReadByte() == 0) { ret = false; } ret = true; } else if (f.FieldType == "Char") { ret = (char)ehdr.r.ReadUInt16(); } else if (f.FieldType == "R4") { ret = ehdr.r.ReadSingle(); } else if (f.FieldType == "R8") { ret = ehdr.r.ReadDouble(); } else if (f.FieldType == "String") { ulong str_ptr = ehdr.ReadPointer((ulong)ehdr.r.BaseStream.Position); ulong str_offset = ehdr.VaddrToOffset(str_ptr); ehdr.r.BaseStream.Seek((long)str_offset + (long)ehdr.stab.ass.GetStringFieldOffset(libtysila.Assembler.StringFields.length), System.IO.SeekOrigin.Begin); int str_len = ehdr.r.ReadInt32(); ehdr.r.BaseStream.Seek((long)str_offset + (long)ehdr.stab.ass.GetStringFieldOffset(libtysila.Assembler.StringFields.data_offset), System.IO.SeekOrigin.Begin); byte[] str_data = ehdr.r.ReadBytes(str_len * 2); ret = Encoding.Unicode.GetString(str_data); } else { // It's an unknown field type, load it as a signed integer switch (f.Length) { case 1: ret = ehdr.r.ReadSByte(); break; case 2: ret = ehdr.r.ReadInt16(); break; case 4: ret = ehdr.r.ReadInt32(); is_obj = true; break; case 8: ret = ehdr.r.ReadInt64(); is_obj = true; break; default: ret = ehdr.r.ReadBytes(f.Length); break; } } } } else if (f.ftype == CMExpLib.Layout.Field.FType.NTArray) { ulong list_vaddr = ehdr.ReadPointer(); if (list_vaddr == 0) { return new object[] {} } ; ulong list_offset = ehdr.VaddrToOffset(list_vaddr); ehdr.r.BaseStream.Seek((long)list_offset, System.IO.SeekOrigin.Begin); ulong cur_item; List <object> items = new List <object>(); do { cur_item = ehdr.ReadPointer(); if (cur_item != 0) { if (read_references) { items.Add(ReadReference(cur_item, ehdr)); } else { items.Add(cur_item); } // The Interfaces list in TysosType is special in that each item is interspersed // with the pointer to the vtable for that interface if ((f.l.Name == "_ZX9TysosTypeTI") && (f.Name == "Interfaces")) { ehdr.ReadPointer(); } } } while (cur_item != 0); ret = items.ToArray(); } if (is_obj && read_references) { ret = ReadReference(Convert.ToUInt64(ret), ehdr); } ehdr.r.BaseStream.Seek(old_pos, System.IO.SeekOrigin.Begin); return(ret); }
private object ReadFieldData(CMExpLib.Layout.Field f, ulong file_offset, Elf64Reader.ElfHeader ehdr) { return(ReadFieldData(f, file_offset, ehdr, true)); }