private static void AssertReadBack(ElfObjectFile elf, string fileName, bool readAsReadOnly) { ElfObjectFile newObjectFile; var filePath = Path.Combine(Environment.CurrentDirectory, fileName); using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { newObjectFile = ElfObjectFile.Read(stream, new ElfReaderOptions() { ReadOnly = readAsReadOnly }); Console.WriteLine(); Console.WriteLine("============================================================================="); Console.WriteLine($"readback {(readAsReadOnly ? "as readonly" : "as readwrite")}"); Console.WriteLine("============================================================================="); Console.WriteLine(); AssertReadElfInternal(newObjectFile, fileName, false, $"Unexpected error while reading back {fileName}"); var originalBuffer = File.ReadAllBytes(filePath); var memoryStream = new MemoryStream(); newObjectFile.Write(memoryStream); var newBuffer = memoryStream.ToArray(); Assert.AreEqual(originalBuffer, newBuffer, "Invalid binary diff between write -> (original) -> read -> write -> (new)"); } }
public void SimpleDwarf() { var cppName = "helloworld"; var cppExe = $"{cppName}_debug"; LinuxUtil.RunLinuxExe("gcc", $"{cppName}.cpp -g -o {cppExe}"); ElfObjectFile elf; using (var inStream = File.OpenRead(cppExe)) { Console.WriteLine($"ReadBack from {cppExe}"); elf = ElfObjectFile.Read(inStream); elf.Print(Console.Out); } var debugInfo = (ElfCustomSection)elf.Sections.FirstOrDefault(x => x.Name.Value == ".debug_info"); var debugAbbrev = (ElfCustomSection)elf.Sections.FirstOrDefault(x => x.Name.Value == ".debug_abbrev"); var debugStr = (ElfCustomSection)elf.Sections.FirstOrDefault(x => x.Name.Value == ".debug_str"); //var dwarfReader = new DwarfReaderWriter(debugInfo.Stream, debugAbbrev.Stream, debugStr.Stream); DwarfDebugStringTable stringTable = new DwarfDebugStringTable() { Stream = debugStr.Stream }; DwarfDebugAbbrevTable abbrevTable = new DwarfDebugAbbrevTable() { Stream = debugAbbrev.Stream }; var debugInfoReadContext = new DwarfDebugInfoReadContext(stringTable, abbrevTable); DwarfDebugInfoSection.TryRead(debugInfo.Stream, elf.Encoding == ElfEncoding.Lsb, debugInfoReadContext, out var debugInfoSection, out var diagnostics); }
public void TestHelloWorld() { var cppName = "helloworld"; LinuxUtil.RunLinuxExe("gcc", $"{cppName}.cpp -o {cppName}"); ElfObjectFile elf; using (var inStream = File.OpenRead(cppName)) { Console.WriteLine($"ReadBack from {cppName}"); elf = ElfObjectFile.Read(inStream); elf.Print(Console.Out); } using (var outStream = File.OpenWrite($"{cppName}_copy")) { elf.Write(outStream); outStream.Flush(); } var expected = LinuxUtil.ReadElf(cppName); var result = LinuxUtil.ReadElf($"{cppName}_copy"); if (expected != result) { Console.WriteLine("=== Result:"); Console.WriteLine(result); Console.WriteLine("=== Expected:"); Console.WriteLine(expected); Assert.AreEqual(expected, result); } }
public void Run() { foreach (var file in Files) { using var stream = new FileStream(file, FileMode.Open, FileAccess.Read); if (ArArchiveFile.IsAr(stream)) { var options = new ArArchiveFileReaderOptions(ArArchiveKind.GNU); var archive = ArArchiveFile.Read(stream, options); foreach (var objFile in archive.Files) { if (objFile is ArElfFile elfFile) { ProcessElf(objFile.Name, elfFile.ElfObjectFile); } } } else if (ElfObjectFile.IsElf(stream)) { var elfObjectFile = ElfObjectFile.Read(stream, new ElfReaderOptions() { ReadOnly = true }); ProcessElf(Path.GetFileName(file), elfObjectFile); } } }
public void TestDebugInfoSmall() { var cppName = "small"; var cppObj = $"{cppName}_debug.o"; LinuxUtil.RunLinuxExe("gcc", $"{cppName}.cpp -g -c -o {cppObj}"); ElfObjectFile elf; using (var inStream = File.OpenRead(cppObj)) { elf = ElfObjectFile.Read(inStream); elf.Print(Console.Out); } var elfContext = new DwarfElfContext(elf); var inputContext = new DwarfReaderContext(elfContext); var dwarf = DwarfFile.Read(inputContext); dwarf.AbbreviationTable.Print(Console.Out); dwarf.InfoSection.Print(Console.Out); dwarf.AddressRangeTable.Print(Console.Out); PrintStreamLength(inputContext); Console.WriteLine(); Console.WriteLine("===================================================================="); Console.WriteLine("Write Back"); Console.WriteLine("===================================================================="); var outputContext = new DwarfWriterContext { IsLittleEndian = inputContext.IsLittleEndian, AddressSize = inputContext.AddressSize, DebugAbbrevStream = new MemoryStream(), DebugLineStream = new MemoryStream(), DebugInfoStream = new MemoryStream(), DebugStringStream = new MemoryStream(), DebugAddressRangeStream = new MemoryStream() }; dwarf.Write(outputContext); dwarf.AbbreviationTable.Print(Console.Out); dwarf.InfoSection.Print(Console.Out); dwarf.InfoSection.PrintRelocations(Console.Out); dwarf.AddressRangeTable.Print(Console.Out); dwarf.AddressRangeTable.PrintRelocations(Console.Out); dwarf.WriteToElf(elfContext); var cppObj2 = $"{cppName}_debug2.o"; using (var outStream = new FileStream(cppObj2, FileMode.Create)) { elf.Write(outStream); } PrintStreamLength(outputContext); }
public void TestDebugLineSmall() { var cppName = "small"; var cppObj = $"{cppName}_debug.o"; LinuxUtil.RunLinuxExe("gcc", $"{cppName}.cpp -g -c -o {cppObj}"); ElfObjectFile elf; using (var inStream = File.OpenRead(cppObj)) { Console.WriteLine($"ReadBack from {cppObj}"); elf = ElfObjectFile.Read(inStream); elf.Print(Console.Out); } var elfContext = new DwarfElfContext(elf); var inputContext = new DwarfReaderContext(elfContext); inputContext.DebugLinePrinter = Console.Out; var dwarf = DwarfFile.Read(inputContext); inputContext.DebugLineStream.Position = 0; var copyInputDebugLineStream = new MemoryStream(); inputContext.DebugLineStream.CopyTo(copyInputDebugLineStream); inputContext.DebugLineStream.Position = 0; var outputContext = new DwarfWriterContext { IsLittleEndian = inputContext.IsLittleEndian, AddressSize = inputContext.AddressSize, DebugLineStream = new MemoryStream() }; dwarf.Write(outputContext); Console.WriteLine(); Console.WriteLine("====================================================="); Console.WriteLine("Readback"); Console.WriteLine("====================================================="); Console.WriteLine(); var reloadContext = new DwarfReaderContext() { IsLittleEndian = outputContext.IsLittleEndian, AddressSize = outputContext.AddressSize, DebugLineStream = outputContext.DebugLineStream }; reloadContext.DebugLineStream.Position = 0; reloadContext.DebugLineStream = outputContext.DebugLineStream; reloadContext.DebugLinePrinter = Console.Out; var dwarf2 = DwarfFile.Read(reloadContext); var inputDebugLineBuffer = copyInputDebugLineStream.ToArray(); var outputDebugLineBuffer = ((MemoryStream)reloadContext.DebugLineStream).ToArray(); Assert.AreEqual(inputDebugLineBuffer, outputDebugLineBuffer); }