Skip to content

Commit

Permalink
ctypesparser borland ast: API
Browse files Browse the repository at this point in the history
  • Loading branch information
xvenge00 committed Mar 7, 2019
1 parent da5321f commit 4f3383a
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 8 deletions.
4 changes: 4 additions & 0 deletions include/llvm/Demangle/borland_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ class FunctionNode : public Node
std::shared_ptr<Node> name,
std::shared_ptr<FunctionTypeNode> funcType);

std::shared_ptr<Node> name();

std::shared_ptr<FunctionTypeNode> funcType();

void printLeft(std::ostream &s) const override;

private:
Expand Down
5 changes: 4 additions & 1 deletion include/llvm/Demangle/borland_demangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "llvm/Demangle/demangler_base.h"
#include "llvm/Demangle/context.h"
#include "llvm/Demangle/borland_ast_parser.h"
#include "retdec/ctypes/context.h"

namespace retdec {
namespace demangler {
Expand All @@ -24,13 +25,15 @@ class BorlandDemangler : public Demangler

std::string demangleToString(const std::string &mangled) override;

void demangleToModule(const std::string &mangled, retdec::ctypes::Module &module) override;

private:
static Status astStatusToDemStatus(const borland::BorlandASTParser::Status &parserStatus);

std::string astToString(const std::shared_ptr<borland::Node> &ast) const;

private:
borland::Context _context;
borland::Context _demangleContext;
};

}
Expand Down
7 changes: 7 additions & 0 deletions include/llvm/Demangle/demangler_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#include <string>

namespace retdec {

namespace ctypes {
class Module;
}

namespace demangler {

/**
Expand All @@ -35,6 +40,8 @@ class Demangler

virtual std::string demangleToString(const std::string &mangled) = 0;

virtual void demangleToModule(const std::string &mangled, retdec::ctypes::Module &module) {};

Status status();

protected:
Expand Down
55 changes: 55 additions & 0 deletions include/retdec/ctypesparser/borland_ast_ctypes_parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef RETDEC_BORLAND_AST_CTYPES_PARSER_H
#define RETDEC_BORLAND_AST_CTYPES_PARSER_H

#include "llvm/Demangle/borland_ast.h"
#include "llvm/Demangle/borland_ast_types.h"
#include "retdec/ctypes/module.h"
#include "retdec/ctypes/context.h"
#include "retdec/ctypes/function.h"
#include "retdec/ctypes/type.h"
#include "retdec/ctypes/integral_type.h"

class Parameters;
class VarArgness;

namespace retdec {
namespace ctypesparser {
namespace borland_ast {

class BorlandToCtypesParser
{
public:
enum Status : u_char
{
success = 0,
init,
invalid_ast,
};

public:
BorlandToCtypesParser();

Status status();

void parseInto(
std::shared_ptr <demangler::borland::Node> ast,
retdec::ctypes::Module &module);

private:
std::shared_ptr <ctypes::Function> parseFunction(std::shared_ptr <demangler::borland::FunctionNode> function);
std::shared_ptr <ctypes::Type> parseType(std::shared_ptr <demangler::borland::TypeNode> typeNode);
std::shared_ptr <ctypes::IntegralType> parseIntegralType(std::shared_ptr <demangler::borland::TypeNode> integralNode);
Parameters parseFuncParameters(std::shared_ptr <demangler::borland::ArrayNode> &paramsNode);
ctypes::CallConvention parseCallConvention(demangler::borland::CallConv &callConv);
VarArgness parseVarArgness(bool isVarArg);

private:
Status _status;
std::shared_ptr <ctypes::Context> _context;
};

} // borland_ast
} // ctypesparser
} // retdec

#endif //RETDEC_BORLAND_AST_CTYPES_PARSER_H
3 changes: 2 additions & 1 deletion src/ctypesparser/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
set(CTYPESPARSER_SOURCES
ctypes_parser.cpp
json_ctypes_parser.cpp
borland_ast_ctypes_parser.cpp
)

add_library(retdec-ctypesparser STATIC ${CTYPESPARSER_SOURCES})
target_link_libraries(retdec-ctypesparser retdec-ctypes retdec-utils rapidjson)
target_link_libraries(retdec-ctypesparser retdec-ctypes retdec-utils rapidjson llvm-demangler)
target_include_directories(retdec-ctypesparser PUBLIC ${PROJECT_SOURCE_DIR}/include/)
92 changes: 92 additions & 0 deletions src/ctypesparser/borland_ast_ctypes_parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <cassert>

#include "retdec/ctypesparser/borland_ast_ctypes_parser.h"
#include "llvm/Demangle/borland_ast.h"
#include "retdec/ctypes/type.h"
#include "retdec/ctypes/function.h"
#include "retdec/ctypes/unknown_type.h"

using Kind = retdec::demangler::borland::Node::Kind;

namespace retdec {
namespace ctypesparser {
namespace borland_ast {

BorlandToCtypesParser::BorlandToCtypesParser() :
_status(init), _context(nullptr) {}

BorlandToCtypesParser::Status BorlandToCtypesParser::status()
{
return _status;
}

void BorlandToCtypesParser::parseInto(
std::shared_ptr<retdec::demangler::borland::Node> ast,
retdec::ctypes::Module &module)
{
assert(ast && "Ast cannot be null");

_context = module.getContext();

switch (ast->kind()) {
case Kind::KFunction: {
auto func = parseFunction(std::static_pointer_cast<demangler::borland::FunctionNode>(ast));
if (func) {
module.addFunction(func);
_status = success;
}
break;
}
default:
_status = invalid_ast;
}
}

std::shared_ptr<retdec::ctypes::Function> BorlandToCtypesParser::parseFunction(std::shared_ptr<demangler::borland::FunctionNode> function)
{
std::string name = function->name()->str(); // TODO null on name()

auto funcType = function->funcType();

std::shared_ptr<ctypes::Type> returnType = parseType(funcType->retType());
// ctypes::Function::Parameters parameters = parseFuncParameters(funcType->params());
// ctypes::CallConvention callConvention = parseCallConvention(funcNode->callConv());
// ctypes::Function::VarArgness varArgness = parseVarArgness(funcNode->isVarArg());
//
// // TODO check status
//
// return ctypes::Function::create(_context, name, returnType, Parameters, callConvention, varArgness);
return nullptr;
}

std::shared_ptr<ctypes::Type> BorlandToCtypesParser::parseType(std::shared_ptr<retdec::demangler::borland::TypeNode> typeNode)
{
if (typeNode == nullptr) {
return std::static_pointer_cast<ctypes::Type>(ctypes::UnknownType::create());
}

switch (typeNode->kind()) {
case Kind::KIntegralType:

default:
return std::static_pointer_cast<ctypes::Type>(ctypes::UnknownType::create());
}

}

//std::shared_ptr<ctypes::IntegralType> BorlandToCtypesParser::parseIntegralType(std::shared_ptr<retdec::demangler::borland::TypeNode> integralNode)
//{
//
//}

//Parameters BorlandToCtypesParser::parseFuncParameters(std::shared_ptr<retdec::demangler::borland::ArrayNode> &paramsNode)
//{
// return nullptr;
//// if (paramsNode == nullptr) {
//// return
//// }
//}

} // borland_ast
} // ctypesparser
} // retdec
1 change: 1 addition & 0 deletions src/demangler_llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ set(DEMANGLER_LLVM_SOURCES
)

add_library(llvm-demangler STATIC ${DEMANGLER_LLVM_SOURCES})
target_link_libraries(llvm-demangler retdec-ctypesparser)
target_include_directories(llvm-demangler PUBLIC ${PROJECT_SOURCE_DIR}/include/)
19 changes: 15 additions & 4 deletions src/demangler_llvm/borland_ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ std::shared_ptr<FunctionNode> FunctionNode::create(
new FunctionNode(std::move(name), std::move(funcType)));
}

std::shared_ptr<Node> FunctionNode::name()
{
return _name;
}

std::shared_ptr<FunctionTypeNode> FunctionNode::funcType() {
return _funcNode;
}

/**
* @brief Prints text representation of function.
* @param s Output stream.
Expand Down Expand Up @@ -215,14 +224,16 @@ void NestedNameNode::printLeft(std::ostream &s) const
/**
* @return Higher level nodes in nested name.
*/
std::shared_ptr<Node> NestedNameNode::super() {
std::shared_ptr<Node> NestedNameNode::super()
{
return _super;
}

/**
* @return Lover level node in neste name.
*/
std::shared_ptr<Node> NestedNameNode::name() {
std::shared_ptr<Node> NestedNameNode::name()
{
return _name;
}

Expand Down Expand Up @@ -290,7 +301,7 @@ void NodeArray::printLeft(std::ostream &s) const
*/
std::shared_ptr<Node> NodeArray::get(unsigned i) const
{
return i < _nodes.size() ? _nodes.at(i): nullptr;
return i < _nodes.size() ? _nodes.at(i) : nullptr;
}

/**
Expand Down Expand Up @@ -354,7 +365,7 @@ ConversionOperatorNode::ConversionOperatorNode(
*/
std::shared_ptr<ConversionOperatorNode> ConversionOperatorNode::create(Context &context, std::shared_ptr<Node> type)
{
return std::shared_ptr<ConversionOperatorNode>(new ConversionOperatorNode(type)); // TODO context
return std::shared_ptr<ConversionOperatorNode>(new ConversionOperatorNode(type)); // TODO context
}

/**
Expand Down
19 changes: 17 additions & 2 deletions src/demangler_llvm/borland_demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

#include "llvm/Demangle/borland_demangler.h"
#include "llvm/Demangle/borland_ast_parser.h"
#include "retdec/ctypesparser/borland_ast_ctypes_parser.h"

namespace retdec {
namespace demangler {

/**
* @brief Constructor for borland demangler.
*/
BorlandDemangler::BorlandDemangler() : Demangler("borland"), _context() {}
BorlandDemangler::BorlandDemangler() : Demangler("borland"), _demangleContext() {}

/**
* @brief Demangles name mangled by borland mangling scheme into string.
Expand All @@ -22,12 +23,26 @@ BorlandDemangler::BorlandDemangler() : Demangler("borland"), _context() {}
*/
std::string BorlandDemangler::demangleToString(const std::string &mangled)
{
borland::BorlandASTParser parser{_context};
borland::BorlandASTParser parser{_demangleContext};
parser.parse(mangled);
_status = astStatusToDemStatus(parser.status());
return astToString(parser.ast());
}

void BorlandDemangler::demangleToModule(const std::string &mangled, retdec::ctypes::Module &module)
{
borland::BorlandASTParser astParser{_demangleContext};
astParser.parse(mangled);
_status = astStatusToDemStatus(astParser.status());
if (_status != success) {
return;
}

ctypesparser::borland_ast::BorlandToCtypesParser ctypesParser{};
ctypesParser.parseInto(astParser.ast(), module);
_status = success; // TODO
}

/**
* Checks ast parser status and converts it to demangler status.
* @return Demangler status.
Expand Down
1 change: 1 addition & 0 deletions tests/ctypesparser/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(RETDEC_TESTS_CTYPESPARSER_SOURCES
json_ctypes_parser_tests.cpp
borland_ast_to_ctypes_tests.cpp
)

add_executable(retdec-tests-ctypesparser ${RETDEC_TESTS_CTYPESPARSER_SOURCES})
Expand Down
40 changes: 40 additions & 0 deletions tests/ctypesparser/borland_ast_to_ctypes_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @file tests/demangler/borland_demangler_tests.cpp
* @brief Tests for the borland demangler.
* @copyright (c) 2019 Avast Software, licensed under the MIT license
*/

#include <gtest/gtest.h>

#include "llvm/Demangle/demangler.h"
#include "retdec/ctypes/module.h"
#include "llvm/Demangle/context.h"
#include "retdec/ctypes/context.h"

using namespace ::testing;

namespace retdec {
namespace demangler {
namespace tests {

class BorlandCtypesTests : public Test
{
public:
using status = retdec::demangler::Demangler::Status;

BorlandCtypesTests() :
demangler(retdec::demangler::DemanglerFactory::getDemangler("borland")) {}
protected:
std::unique_ptr<retdec::demangler::Demangler> demangler;
};

TEST_F(BorlandCtypesTests, basic)
{
auto context = std::make_shared<retdec::ctypes::Context>();
ctypes::Module module(context);
demangler->demangleToModule("@myFunc_int_$qi", module);
}

}
}
}

0 comments on commit 4f3383a

Please sign in to comment.