예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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}");
            }
        }
예제 #3
0
        public void CheckCreateArLibrary()
        {
            var libName = "libcustom.a";

            var file = new ArArchiveFile();

            using (var stream = new FileStream(libName, FileMode.Create, FileAccess.Write))
            {
                var symbolTable = new ArSymbolTable();
                file.AddFile(symbolTable);

                file.AddFile(new ArBinaryFile()
                {
                    Name = "file2.txt", OwnerId = 0666, Stream = new MemoryStream(Encoding.UTF8.GetBytes("this is file"))
                });

                file.AddFile(new ArBinaryFile()
                {
                    Name = "file3.txt", OwnerId = 0777, GroupId = 0744, Stream = new MemoryStream(Encoding.UTF8.GetBytes("this is file3"))
                });

                file.AddFile(new ArBinaryFile()
                {
                    Name = "file4.txt", OwnerId = 0777, GroupId = 0744, Stream = new MemoryStream(Encoding.UTF8.GetBytes("this is file4"))
                });

                file.AddFile(new ArBinaryFile()
                {
                    Name = "file5.txt", OwnerId = 0706, GroupId = 0705, FileMode = 0x123456, Stream = new MemoryStream(Encoding.UTF8.GetBytes("this is file5"))
                });

                file.AddFile(new ArBinaryFile()
                {
                    Name = "long_file_name_large_file6.txt", Timestamp = DateTimeOffset.UtcNow.AddSeconds(-2), Stream = new MemoryStream(Encoding.UTF8.GetBytes("this is file6 yoyo"))
                });

                symbolTable.Symbols.Add(new ArSymbol()
                {
                    File = file.Files[1], Name = "my_symbol"
                });

                file.Write(stream);
                stream.Flush();
            }

            // Check that AR is able to read back what we just serialized
            {
                var fileNameBuilder = new StringBuilder();
                foreach (var fileEntry in file.Files)
                {
                    if (fileEntry.IsSystem)
                    {
                        continue;
                    }
                    fileNameBuilder.Append($"{fileEntry.Name}\n");
                }

                var fileNameList       = fileNameBuilder.ToString().Trim();
                var fileNameListFromAr = LinuxUtil.RunLinuxExe("ar", $"t {libName}").Trim();
                Assert.AreEqual(fileNameListFromAr, fileNameList);
            }

            // Display the content of each file via AR
            {
                var contentBuilder = new StringBuilder();
                foreach (var fileEntry in file.Files)
                {
                    if (!(fileEntry is ArBinaryFile arBinary))
                    {
                        continue;
                    }

                    arBinary.Stream.Position = 0;
                    contentBuilder.Append(Encoding.UTF8.GetString(((MemoryStream)arBinary.Stream).ToArray()));
                }

                var content       = contentBuilder.ToString().Trim();
                var contentFromAr = LinuxUtil.RunLinuxExe("ar", $"p {libName}").Trim();
                Assert.AreEqual(contentFromAr, content);
            }

            ArArchiveFile file2;

            using (var stream = new FileStream(libName, FileMode.Open, FileAccess.Read))
            {
                file2 = ArArchiveFile.Read(stream, ArArchiveKind.GNU);
            }

            Assert.NotNull(file2.SymbolTable);
            CompareArFiles(file, file2);

            var libNameBsd = "libcustom_bsd.a";

            file.Kind = ArArchiveKind.BSD;
            using (var stream = new FileStream(libNameBsd, FileMode.Create, FileAccess.Write))
            {
                file.Write(stream);
                stream.Flush();
            }

            ArArchiveFile archiveFileBsd;

            using (var stream = new FileStream(libNameBsd, FileMode.Open, FileAccess.Read))
            {
                archiveFileBsd = ArArchiveFile.Read(stream, ArArchiveKind.BSD);
            }

            CompareArFiles(file, archiveFileBsd);
        }