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 CheckLibraryWithELF() { var cppName = "helloworld"; var cppObj = $"{cppName}.o"; var cppLib = $"lib{cppName}.a"; File.Delete(cppObj); File.Delete(cppLib); LinuxUtil.RunLinuxExe("gcc", $"{cppName}.cpp -c -o {cppObj}"); LinuxUtil.RunLinuxExe("ar", $"rcs {cppLib} {cppObj}"); using (var stream = new FileStream(cppLib, FileMode.Open, FileAccess.Read)) { Assert.True(ArArchiveFile.IsAr(stream)); var arFile = ArArchiveFile.Read(stream, new ArArchiveFileReaderOptions(ArArchiveKind.GNU) { ProcessObjectFiles = false }); var elfFile = arFile.Files.FirstOrDefault(x => x.Name == cppObj); Assert.NotNull(elfFile, $"Unable to find {cppObj} file in {cppLib}"); Assert.NotNull(arFile.SymbolTable, $"Unable to find symbol table in {cppLib}"); Assert.AreEqual(1, arFile.SymbolTable.Symbols.Count, "Invalid number of symbols in Symbol table"); Assert.AreEqual("main", arFile.SymbolTable.Symbols[0].Name, "Invalid symbol found"); Assert.AreEqual(elfFile, arFile.SymbolTable.Symbols[0].File, "Invalid symbol to file found"); var outStream = new MemoryStream(); arFile.Write(outStream); var newArray = outStream.ToArray(); outStream.Position = 0; var cppLibCopy = $"lib{cppName}_copy.a"; using (var copyStream = new FileStream(cppLibCopy, FileMode.Create, FileAccess.Write)) { outStream.CopyTo(copyStream); } var originalStream = new MemoryStream(); stream.Position = 0; stream.CopyTo(originalStream); var originalArray = originalStream.ToArray(); Assert.AreEqual(originalArray, newArray, $"Non binary matching between file {cppLib} and {cppLibCopy}"); } }
public void CheckInvalidHeader() { // Incorrect magic length { var stream = new MemoryStream(new byte[] { 1, 2, 3, 4 }); Assert.False(ArArchiveFile.IsAr(stream, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_InvalidMagicLength); } // Correct length, magic invalid { var stream = new MemoryStream(new byte[] { (byte)'!', (byte)'<', (byte)'a', (byte)'r', (byte)'c', (byte)'h', (byte)'>', (byte)'?', }); Assert.False(ArArchiveFile.IsAr(stream, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_MagicNotFound); } // Valid { var stream = new MemoryStream(new byte[] { (byte)'!', (byte)'<', (byte)'a', (byte)'r', (byte)'c', (byte)'h', (byte)'>', (byte)'\n', }); Assert.True(ArArchiveFile.IsAr(stream, out var diagnostics)); ExpectNoDiagnostics(diagnostics); } }