Browse Source

Added reading of dependencies of Mach-O (OS X) binaries.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/642/head
Dimitar Dobrev 9 years ago
parent
commit
fc84e6bf1e
  1. 52
      src/CppParser/Parser.cpp
  2. 24
      src/Generator.Tests/ParseELFTest.cs
  3. 52
      src/Generator.Tests/ReadNativeDependenciesTest.cs
  4. 0
      tests/Native/ls-linux
  5. BIN
      tests/Native/ls-osx
  6. BIN
      tests/Native/ls-windows

52
src/CppParser/Parser.cpp

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
#include <llvm/Object/COFF.h>
#include <llvm/Object/ObjectFile.h>
#include <llvm/Object/ELFObjectFile.h>
#include <llvm/Object/MachO.h>
#include <llvm/Option/ArgList.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
@ -3302,31 +3303,48 @@ ParserResultKind Parser::ParseSharedLib(llvm::StringRef File, @@ -3302,31 +3303,48 @@ ParserResultKind Parser::ParseSharedLib(llvm::StringRef File,
{
ReadELFDependencies(ELFObjectFile->getELFFile(), NativeLib);
}
return ParserResultKind::Success;
}
else
if (ObjectFile->isCOFF())
{
if (auto COFFObjectFile = llvm::dyn_cast<llvm::object::COFFObjectFile>(ObjectFile))
auto COFFObjectFile = static_cast<llvm::object::COFFObjectFile*>(ObjectFile);
for (auto ExportedSymbol : COFFObjectFile->export_directories())
{
for (auto ExportedSymbol : COFFObjectFile->export_directories())
{
llvm::StringRef Symbol;
if (!ExportedSymbol.getSymbolName(Symbol))
NativeLib->Symbols.push_back(Symbol);
}
for (auto ImportedSymbol : COFFObjectFile->import_directories())
{
llvm::StringRef Name;
if (!ImportedSymbol.getName(Name) && (Name.endswith(".dll") || Name.endswith(".DLL")))
NativeLib->Dependencies.push_back(Name);
}
llvm::StringRef Symbol;
if (!ExportedSymbol.getSymbolName(Symbol))
NativeLib->Symbols.push_back(Symbol);
}
else
for (auto ImportedSymbol : COFFObjectFile->import_directories())
{
return ParserResultKind::Error;
llvm::StringRef Name;
if (!ImportedSymbol.getName(Name) && (Name.endswith(".dll") || Name.endswith(".DLL")))
NativeLib->Dependencies.push_back(Name);
}
return ParserResultKind::Success;
}
return ParserResultKind::Success;
if (ObjectFile->isMachO())
{
auto MachOObjectFile = static_cast<llvm::object::MachOObjectFile*>(ObjectFile);
for (const auto &Load : MachOObjectFile->load_commands())
{
if (Load.C.cmd == llvm::MachO::LC_ID_DYLIB ||
Load.C.cmd == llvm::MachO::LC_LOAD_DYLIB ||
Load.C.cmd == llvm::MachO::LC_LOAD_WEAK_DYLIB ||
Load.C.cmd == llvm::MachO::LC_REEXPORT_DYLIB ||
Load.C.cmd == llvm::MachO::LC_LAZY_LOAD_DYLIB ||
Load.C.cmd == llvm::MachO::LC_LOAD_UPWARD_DYLIB)
{
auto dl = MachOObjectFile->getDylibIDLoadCommand(Load);
auto lib = llvm::sys::path::filename(Load.Ptr + dl.dylib.name);
NativeLib->Dependencies.push_back(lib);
}
}
return ParserResultKind::Success;
}
return ParserResultKind::Error;
}
ParserResultKind Parser::ReadSymbols(llvm::StringRef File,

24
src/Generator.Tests/ParseELFTest.cs

@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
using CppSharp.Utils;
using NUnit.Framework;
namespace CppSharp.Generator.Tests
{
[TestFixture]
public class ParseELFTest
{
[Test]
public void TestParseELF()
{
var driverOptions = new DriverOptions();
driverOptions.addLibraryDirs(GeneratorTest.GetTestsDirectory("Native"));
driverOptions.Libraries.Add("ls");
var driver = new Driver(driverOptions, new TextDiagnosticPrinter());
Assert.IsTrue(driver.ParseLibraries());
var dependencies = driver.Symbols.Libraries[0].Dependencies;
Assert.AreEqual("libselinux.so.1", dependencies[0]);
Assert.AreEqual("librt.so.1", dependencies[1]);
Assert.AreEqual("libacl.so.1", dependencies[2]);
Assert.AreEqual("libc.so.6", dependencies[3]);
}
}
}

52
src/Generator.Tests/ReadNativeDependenciesTest.cs

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
using CppSharp.Utils;
using NUnit.Framework;
namespace CppSharp.Generator.Tests
{
[TestFixture]
public class ReadNativeDependenciesTest
{
[Test]
public void TestReadDependenciesWindows()
{
var driverOptions = new DriverOptions();
driverOptions.addLibraryDirs(GeneratorTest.GetTestsDirectory("Native"));
driverOptions.Libraries.Add("ls-windows");
var driver = new Driver(driverOptions, new TextDiagnosticPrinter());
Assert.IsTrue(driver.ParseLibraries());
var dependencies = driver.Symbols.Libraries[0].Dependencies;
Assert.AreEqual("msys-intl-8.dll", dependencies[0]);
Assert.AreEqual("msys-2.0.dll", dependencies[1]);
Assert.AreEqual("KERNEL32.dll", dependencies[2]);
}
[Test]
public void TestReadDependenciesLinux()
{
var driverOptions = new DriverOptions();
driverOptions.addLibraryDirs(GeneratorTest.GetTestsDirectory("Native"));
driverOptions.Libraries.Add("ls-linux");
var driver = new Driver(driverOptions, new TextDiagnosticPrinter());
Assert.IsTrue(driver.ParseLibraries());
var dependencies = driver.Symbols.Libraries[0].Dependencies;
Assert.AreEqual("libselinux.so.1", dependencies[0]);
Assert.AreEqual("librt.so.1", dependencies[1]);
Assert.AreEqual("libacl.so.1", dependencies[2]);
Assert.AreEqual("libc.so.6", dependencies[3]);
}
[Test]
public void TestReadDependenciesOSX()
{
var driverOptions = new DriverOptions();
driverOptions.addLibraryDirs(GeneratorTest.GetTestsDirectory("Native"));
driverOptions.Libraries.Add("ls-osx");
var driver = new Driver(driverOptions, new TextDiagnosticPrinter());
Assert.IsTrue(driver.ParseLibraries());
var dependencies = driver.Symbols.Libraries[0].Dependencies;
Assert.AreEqual("libutil.dylib", dependencies[0]);
Assert.AreEqual("libncurses.5.4.dylib", dependencies[1]);
Assert.AreEqual("libSystem.B.dylib", dependencies[2]);
}
}
}

0
tests/Native/ls → tests/Native/ls-linux

BIN
tests/Native/ls-osx

Binary file not shown.

BIN
tests/Native/ls-windows

Binary file not shown.
Loading…
Cancel
Save