public void Read(ParsedDocument doc, ElfSectionHeader section, byte[] data) { var header = doc.document.header; symbols.Clear(); using (var ms = new System.IO.MemoryStream(data)) { int sylsize = header.Head_Is64Bit ? 24 : 16; for (var i = 0; i < data.Length; i += sylsize) { Symbol symbol = new Symbol(); if (header.Head_Is64Bit)//64位和32位格式,顺序不太一样 { symbol.st_name = ms.ReadUInt32(header); symbol.st_info = ms.ReadByte1(); symbol.st_other = ms.ReadByte1(); symbol.st_shndx = ms.ReadUInt16(header); symbol.st_value = ms.ReadUIntPtr(header); symbol.st_size = ms.ReadUIntPtr(header); } else { symbol.st_name = ms.ReadUInt32(header); symbol.st_value = ms.ReadUIntPtr(header); symbol.st_size = ms.ReadUIntPtr(header); symbol.st_info = ms.ReadByte1(); symbol.st_other = ms.ReadByte1(); symbol.st_shndx = ms.ReadUInt16(header); } if (doc.Parsed_StringTables.ContainsKey((int)section.Link)) { var stable = doc.Parsed_StringTables[(int)section.Link]; stable.TryGetValue((int)symbol.st_name, out symbol.Name); } symbol.SymbolBinding = (SymbolBinding)(symbol.st_info >> 4); symbol.SymbolType = (SymbolType)(symbol.st_info & 0x0F); if (Enum.IsDefined(typeof(SpecialSectionIndex), symbol.st_shndx)) { symbol.SpecialSectionIndex = (SpecialSectionIndex)symbol.st_shndx; } else { symbol.SpecialSectionIndex = null; } symbols.Add(symbol); } } }
public void Read(ParsedDocument doc, ElfSectionHeader section, byte[] data) { var header = doc.document.header; Relocations.Clear(); using (var ms = new System.IO.MemoryStream(data)) { int sylsize = header.Head_Is64Bit ? 8 : 4; if (haveAppend) { sylsize = sylsize * 3; } else { sylsize = sylsize * 2; } for (var i = 0; i < data.Length; i += sylsize) { Relocation reloc = new Relocation(); reloc.r_offset = ms.ReadUIntPtr(header); reloc.r_info = ms.ReadUIntPtr(header); if (this.haveAppend) { reloc.r_append = ms.ReadUIntPtr(header); } if (header.Head_Is64Bit) { reloc.symAddr = (uint)(reloc.r_info >> 32); reloc.relocType = (uint)(reloc.r_info); } else { reloc.symAddr = (uint)(reloc.r_info >> 8); reloc.relocType = (byte)(reloc.r_info); } Relocations.Add(reloc); } } }
internal override unsafe bool GetFileVersion(string dll, out int major, out int minor, out int revision, out int patch) { using FileStream stream = File.OpenRead(dll); StreamAddressSpace streamAddressSpace = new StreamAddressSpace(stream); Reader streamReader = new Reader(streamAddressSpace); ElfFile file = new ElfFile(streamReader); IElfHeader header = file.Header; ElfSectionHeader headerStringHeader = new ElfSectionHeader(streamReader, header.Is64Bit, header.SectionHeaderOffset + header.SectionHeaderStringIndex * header.SectionHeaderEntrySize); long headerStringOffset = (long)headerStringHeader.FileOffset; long dataOffset = 0; long dataSize = 0; for (int i = 0; i < header.SectionHeaderCount; i++) { if (i == header.SectionHeaderStringIndex) { continue; } ElfSectionHeader sectionHeader = new ElfSectionHeader(streamReader, header.Is64Bit, header.SectionHeaderOffset + i * header.SectionHeaderEntrySize); if (sectionHeader.Type == ElfSectionHeaderType.ProgBits) { string sectionName = streamReader.ReadNullTerminatedAscii(headerStringOffset + sectionHeader.NameIndex * sizeof(byte)); if (sectionName == ".data") { dataOffset = (long)sectionHeader.FileOffset; dataSize = (long)sectionHeader.FileSize; break; } } } DebugOnly.Assert(dataOffset != 0); DebugOnly.Assert(dataSize != 0); Span <byte> buffer = stackalloc byte[s_versionLength]; long address = dataOffset; long endAddress = address + dataSize; while (address < endAddress) { int read = streamAddressSpace.Read(address, buffer); if (read < s_versionLength) { break; } if (!buffer.SequenceEqual(s_versionString)) { address++; continue; } address += s_versionLength; // TODO: This should be cleaned up to not read byte by byte in the future. Leaving it here // until we decide whether to rewrite the Linux coredumpreader or not. StringBuilder builder = new StringBuilder(); while (address < endAddress) { Span <byte> bytes = stackalloc byte[1]; read = streamAddressSpace.Read(address, bytes); if (read < bytes.Length) { break; } if (bytes[0] == '\0') { break; } if (bytes[0] == ' ') { try { Version v = Version.Parse(builder.ToString()); major = v.Major; minor = v.Minor; revision = v.Build; patch = v.Revision; return(true); } catch (FormatException) { break; } } Span <char> chars = stackalloc char[1]; fixed(byte *bytesPtr = &MemoryMarshal.GetReference(bytes)) fixed(char *charsPtr = &MemoryMarshal.GetReference(chars)) { _ = Encoding.ASCII.GetChars(bytesPtr, bytes.Length, charsPtr, chars.Length); } _ = builder.Append(chars[0]); address++; } break; } major = minor = revision = patch = 0; return(false); }