Browse Source

Merge pull request #294 from ddobrev/master

Extended the collection of library symbols to handle ELF shared objects
pull/296/head
João Matos 12 years ago
parent
commit
5013397bcb
  1. 87
      src/CppParser/Parser.cpp
  2. 17
      src/CppParser/Parser.h

87
src/CppParser/Parser.cpp

@ -12,6 +12,7 @@
#include <llvm/Support/raw_ostream.h> #include <llvm/Support/raw_ostream.h>
#include <llvm/Object/Archive.h> #include <llvm/Object/Archive.h>
#include <llvm/Object/ObjectFile.h> #include <llvm/Object/ObjectFile.h>
#include <llvm/Object/ELFObjectFile.h>
#include <llvm/IR/LLVMContext.h> #include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h> #include <llvm/IR/Module.h>
#include <llvm/IR/DataLayout.h> #include <llvm/IR/DataLayout.h>
@ -2984,20 +2985,14 @@ ParserResult* Parser::ParseHeader(const std::string& File, ParserResult* res)
} }
ParserResultKind Parser::ParseArchive(llvm::StringRef File, ParserResultKind Parser::ParseArchive(llvm::StringRef File,
std::unique_ptr<llvm::MemoryBuffer>& Buffer, llvm::object::Archive* Archive,
CppSharp::CppParser::NativeLibrary*& NativeLib) CppSharp::CppParser::NativeLibrary*& NativeLib)
{ {
std::error_code Code;
llvm::object::Archive Archive(std::move(Buffer), Code);
if (Code)
return ParserResultKind::Error;
auto LibName = File; auto LibName = File;
NativeLib = new NativeLibrary(); NativeLib = new NativeLibrary();
NativeLib->FileName = LibName; NativeLib->FileName = LibName;
for(auto it = Archive.symbol_begin(); it != Archive.symbol_end(); ++it) for(auto it = Archive->symbol_begin(); it != Archive->symbol_end(); ++it)
{ {
llvm::StringRef SymRef = it->getName(); llvm::StringRef SymRef = it->getName();
NativeLib->Symbols.push_back(SymRef); NativeLib->Symbols.push_back(SymRef);
@ -3007,33 +3002,34 @@ ParserResultKind Parser::ParseArchive(llvm::StringRef File,
} }
ParserResultKind Parser::ParseSharedLib(llvm::StringRef File, ParserResultKind Parser::ParseSharedLib(llvm::StringRef File,
std::unique_ptr<llvm::MemoryBuffer>& Buffer, llvm::object::SymbolicFile* SymbolicFile,
CppSharp::CppParser::NativeLibrary*& NativeLib) CppSharp::CppParser::NativeLibrary*& NativeLib)
{ {
auto Object = llvm::object::ObjectFile::createObjectFile(Buffer); if (!SymbolicFile->isELF())
if (!Object)
return ParserResultKind::Error; return ParserResultKind::Error;
auto LibName = File; auto IDyn = llvm::object::getELFDynamicSymbolIterators(SymbolicFile);
NativeLib = new NativeLibrary();
NativeLib->FileName = LibName;
std::error_code ec; return ReadSymbols(File, IDyn.first, IDyn.second, NativeLib);
for(auto it = Object.get()->symbol_begin(); it != Object.get()->symbol_end(); }
++it)
{
std::string Sym;
llvm::raw_string_ostream SymStream(Sym);
if (it->printName(SymStream)) ParserResultKind Parser::ParseObjectFile(llvm::StringRef File,
continue; llvm::object::ObjectFile* ObjectFile,
CppSharp::CppParser::NativeLibrary*& NativeLib)
{
return ReadSymbols(File, ObjectFile->symbol_begin(), ObjectFile->symbol_end(), NativeLib);
}
NativeLib->Symbols.push_back(Sym); ParserResultKind Parser::ReadSymbols(llvm::StringRef File,
} llvm::object::basic_symbol_iterator Begin,
llvm::object::basic_symbol_iterator End,
CppSharp::CppParser::NativeLibrary*& NativeLib)
{
auto LibName = File;
NativeLib = new NativeLibrary();
NativeLib->FileName = LibName;
for (auto it = Object.get()->symbol_begin(); it != Object.get()->symbol_end(); for (auto it = Begin; it != End; ++it)
++it)
{ {
std::string Sym; std::string Sym;
llvm::raw_string_ostream SymStream(Sym); llvm::raw_string_ostream SymStream(Sym);
@ -3041,7 +3037,9 @@ ParserResultKind Parser::ParseSharedLib(llvm::StringRef File,
if (it->printName(SymStream)) if (it->printName(SymStream))
continue; continue;
NativeLib->Symbols.push_back(Sym); SymStream.flush();
if (!Sym.empty())
NativeLib->Symbols.push_back(Sym);
} }
return ParserResultKind::Success; return ParserResultKind::Success;
@ -3078,16 +3076,31 @@ ParserResultKind Parser::ParseSharedLib(llvm::StringRef File,
} }
std::unique_ptr<llvm::MemoryBuffer> FileBuf(FM.getBufferForFile(FileEntry)); std::unique_ptr<llvm::MemoryBuffer> FileBuf(FM.getBufferForFile(FileEntry));
res->Kind = ParseArchive(File, FileBuf, res->Library); auto BinaryOrErr = llvm::object::createBinary(std::move(FileBuf), &llvm::getGlobalContext());
if (BinaryOrErr.getError())
if (res->Kind == ParserResultKind::Success) {
return res; res->Kind = ParserResultKind::Error;
res->Kind = ParseSharedLib(File, FileBuf, res->Library);
if (res->Kind == ParserResultKind::Success)
return res; return res;
}
std::unique_ptr<llvm::object::Binary> Bin(BinaryOrErr.get());
if (auto Archive = llvm::dyn_cast<llvm::object::Archive>(Bin.get())) {
res->Kind = ParseArchive(File, Archive, res->Library);
if (res->Kind == ParserResultKind::Success)
return res;
}
if (auto SymbolicFile = llvm::dyn_cast<llvm::object::SymbolicFile>(Bin.get()))
{
res->Kind = ParseSharedLib(File, SymbolicFile, res->Library);
if (res->Kind == ParserResultKind::Success)
return res;
}
if (auto ObjectFile = llvm::dyn_cast<llvm::object::ObjectFile>(Bin.get()))
{
res->Kind = ParseObjectFile(File, ObjectFile, res->Library);
if (res->Kind == ParserResultKind::Success)
return res;
}
res->Kind = ParserResultKind::Error;
return res; return res;
} }

17
src/CppParser/Parser.h

@ -7,6 +7,10 @@
#pragma once #pragma once
#include <llvm/Object/Archive.h>
#include <llvm/Object/ObjectFile.h>
#include <llvm/Object/SymbolicFile.h>
#include <clang/AST/ASTFwd.h> #include <clang/AST/ASTFwd.h>
#include <clang/AST/Type.h> #include <clang/AST/Type.h>
#include <clang/Basic/TargetInfo.h> #include <clang/Basic/TargetInfo.h>
@ -48,11 +52,14 @@ public:
ParserResult* ParseHeader(const std::string& File, ParserResult* res); ParserResult* ParseHeader(const std::string& File, ParserResult* res);
ParserResult* ParseLibrary(const std::string& File, ParserResult* res); ParserResult* ParseLibrary(const std::string& File, ParserResult* res);
ParserResultKind ParseArchive(llvm::StringRef File, ParserResultKind ParseArchive(llvm::StringRef File,
std::unique_ptr<llvm::MemoryBuffer>& Buffer, llvm::object::Archive* Archive,
CppSharp::CppParser::NativeLibrary*& NativeLib); CppSharp::CppParser::NativeLibrary*& NativeLib);
ParserResultKind ParseSharedLib(llvm::StringRef File, ParserResultKind ParseSharedLib(llvm::StringRef File,
std::unique_ptr<llvm::MemoryBuffer>& Buffer, llvm::object::SymbolicFile* SymbolicFile,
CppSharp::CppParser::NativeLibrary*& NativeLib); CppSharp::CppParser::NativeLibrary*& NativeLib);
ParserResultKind ParseObjectFile(llvm::StringRef File,
llvm::object::ObjectFile* ObjectFile,
CppSharp::CppParser::NativeLibrary*& NativeLib);
ParserTargetInfo* GetTargetInfo(); ParserTargetInfo* GetTargetInfo();
protected: protected:
@ -132,6 +139,12 @@ protected:
clang::TargetCXXABI::Kind TargetABI; clang::TargetCXXABI::Kind TargetABI;
clang::TargetCodeGenInfo* CodeGenInfo; clang::TargetCodeGenInfo* CodeGenInfo;
clang::CodeGen::CodeGenTypes* CodeGenTypes; clang::CodeGen::CodeGenTypes* CodeGenTypes;
private:
ParserResultKind ReadSymbols(llvm::StringRef File,
llvm::object::basic_symbol_iterator Begin,
llvm::object::basic_symbol_iterator End,
CppSharp::CppParser::NativeLibrary*& NativeLib);
}; };
} } } }
Loading…
Cancel
Save