Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

codegen: support to emit hl mlir and llvm ir #53

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ Checks: "*,\
-google-build-using-namespace, \
-cppcoreguidelines-owning-memory, \
-readability-identifier-length, \
-readability-function-cognitive-complexity "
-readability-function-cognitive-complexity, \
-cppcoreguidelines-pro-type-const-cast, \
-clang-tidycppcoreguidelines-avoid-const-or-ref-data-members "
WarningsAsErrors: ''
CheckOptions:
- key: 'bugprone-argument-comment.StrictMode'
Expand Down
19 changes: 9 additions & 10 deletions include/patchestry/AST/ASTConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include "patchestry/Util/Options.hpp"
#include <functional>
#include <memory>
#include <unordered_map>
Expand All @@ -23,7 +24,6 @@
#include <clang/Sema/Sema.h>
#include <llvm/Support/raw_ostream.h>

#include <patchestry/AST/Codegen.hpp>
#include <patchestry/AST/TypeBuilder.hpp>
#include <patchestry/Ghidra/JsonDeserialize.hpp>
#include <patchestry/Ghidra/PcodeOperations.hpp>
Expand All @@ -38,16 +38,16 @@ namespace patchestry::ast {
{
public:
explicit PcodeASTConsumer(
clang::CompilerInstance &ci, Program &prog, std::string &outfile
clang::CompilerInstance &ci, Program &prog, patchestry::Options &opts
)
: program(prog)
, ci(ci)
, outfile(outfile)
, codegen(std::make_unique< CodeGenerator >(ci))
, type_builder(std::make_unique< TypeBuilder >(ci.getASTContext())) {}
: options(opts), program(prog), ci(ci), type_builder(nullptr) {}

void HandleTranslationUnit(clang::ASTContext &ctx) override;

const std::unordered_map< void *, std::string > &locations(void) const {
return location_map;
}

private:
void set_sema_context(clang::DeclContext *dc);

Expand All @@ -63,11 +63,10 @@ namespace patchestry::ast {

clang::Sema &sema(void) const { return ci.get().getSema(); }

const patchestry::Options &options;

std::reference_wrapper< Program > program;
std::reference_wrapper< clang::CompilerInstance > ci;

std::string outfile;
std::unique_ptr< CodeGenerator > codegen;
std::unique_ptr< TypeBuilder > type_builder;

std::unordered_map< std::string, clang::FunctionDecl * > function_declarations;
Expand Down
46 changes: 0 additions & 46 deletions include/patchestry/AST/Codegen.hpp

This file was deleted.

6 changes: 5 additions & 1 deletion include/patchestry/AST/OperationBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,13 @@ namespace patchestry::ast {
* occurs.
*/
clang::Expr *perform_explicit_cast(
clang::ASTContext &ctx, clang::Expr *expr, clang::QualType to_type
clang::ASTContext &ctx, clang::Expr *expr, clang::QualType to_type,
const std::string &location_key
);

bool
try_implicit_cast(clang::ASTContext &ctx, clang::Expr *expr, clang::QualType to_type);

clang::Stmt *create_varnode(
clang::ASTContext &ctx, const Function &function, const Varnode &vnode,
const std::string &op_key = ""
Expand Down
14 changes: 13 additions & 1 deletion include/patchestry/AST/TypeBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ namespace patchestry::ast {
static constexpr uint32_t num_bits_in_byte = 8U;
static constexpr uint32_t num_bits_uint = 32U;

explicit TypeBuilder(clang::ASTContext &ctx) : context(ctx), serialized_types({}) {}
explicit TypeBuilder(
clang::ASTContext &ctx, std::unordered_map< void *, std::string > &locations
)
: location_map(locations), context(ctx), serialized_types({}) {}

TypeBuilder &operator=(const TypeBuilder &) = delete;
TypeBuilder(const TypeBuilder &) = delete;
Expand All @@ -34,6 +37,13 @@ namespace patchestry::ast {

virtual ~TypeBuilder() = default;

template< typename T >
void set_location_key(T *pointer, const std::string &key) {
if (!location_map.get().contains(pointer)) {
location_map.get().emplace(pointer, key);
}
}

/**
* @brief Provides access to the serialized type map.
*
Expand Down Expand Up @@ -199,6 +209,8 @@ namespace patchestry::ast {

std::unordered_map< std::string, clang::Decl * > missing_type_definition;

std::reference_wrapper< std::unordered_map< void *, std::string > > location_map;

std::reference_wrapper< clang::ASTContext > context;
SerializedTypeMap serialized_types;
};
Expand Down
110 changes: 110 additions & 0 deletions include/patchestry/Codegen/Codegen.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2024, Trail of Bits, Inc.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include "patchestry/Util/Options.hpp"
#include <mlir/IR/MLIRContext.h>
#include <unordered_map>

#include <clang/AST/ASTContext.h>
#include <clang/Frontend/CompilerInstance.h>
#include <mlir/Pass/PassRegistry.h>

#include <vast/Frontend/FrontendAction.hpp>
#include <vast/Frontend/Options.hpp>
#include <vast/Frontend/Targets.hpp>

namespace llvm {
class raw_fd_ostream;
} // namespace llvm

namespace patchestry::codegen {

using LocationMap = std::unordered_map< void *, std::string >;

class MLIRRegistryInitializer
{
public:
explicit MLIRRegistryInitializer(mlir::DialectRegistry &registry);
};

class CodegenInitializer
{
public:
// Delete copy and move constructors and assignment operators
CodegenInitializer(const CodegenInitializer &) = delete;
CodegenInitializer &operator=(const CodegenInitializer &) = delete;
CodegenInitializer(CodegenInitializer &&) noexcept = delete;
CodegenInitializer &operator=(CodegenInitializer &&) noexcept = delete;

// Public static method to access the singleton instance
static CodegenInitializer &getInstance() {
static CodegenInitializer instance(0);
return instance;
}

inline mlir::MLIRContext &context() const noexcept { return ctx; }

~CodegenInitializer();

private:
explicit CodegenInitializer(int /*unused*/);

// Members
mlir::DialectRegistry registry;
MLIRRegistryInitializer registry_initializer;
mutable mlir::MLIRContext ctx;
};

class CodeGenerator

{
public:
explicit CodeGenerator(clang::CompilerInstance &ci) : opts(vast::cc::options(ci)) {}

CodeGenerator(const CodeGenerator &) = delete;
CodeGenerator &operator=(const CodeGenerator &) = delete;
CodeGenerator(CodeGenerator &&) noexcept = delete;
CodeGenerator &operator=(CodeGenerator &&) noexcept = delete;

virtual ~CodeGenerator() = default;

void emit_tower(
clang::ASTContext &actx, const LocationMap &locations,
const patchestry::Options &options
);

void emit_source_ir(
clang::ASTContext &actx, const LocationMap &locations,
const patchestry::Options &options
);

private:
void process_mlir_module(
clang::ASTContext &actx, vast::cc::target_dialect target, vast::mlir_module mod
);

void emit_mlir_after_pipeline(
clang::ASTContext &actx, vast::mlir_module mod, const patchestry::Options &options
);

void emit_llvmir(
clang::ASTContext &actx, vast::mlir_module mod, const patchestry::Options &options
);

void emit_asm(
clang::ASTContext &actx, vast::mlir_module mod, const patchestry::Options &options
);

std::optional< vast::owning_mlir_module_ref >
emit_mlir(clang::ASTContext &ctx, const LocationMap &locations);

vast::cc::action_options opts;
};

} // namespace patchestry::codegen
47 changes: 47 additions & 0 deletions include/patchestry/Codegen/MetaGenerator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024, Trail of Bits, Inc.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include <clang/AST/ASTContext.h>
#include <mlir/IR/MLIRContext.h>

#define GAP_ENABLE_COROUTINES
#include <vast/CodeGen/CodeGenMetaGenerator.hpp>

#include <patchestry/Codegen/Codegen.hpp>

namespace patchestry::codegen {

struct MetaGen final : vast::cg::meta_generator
{
MetaGen(clang::ASTContext *actx, mlir::MLIRContext *mctx, const LocationMap &locs);

void *raw_pointer(const clang::Decl *decl) const;

void *raw_pointer(const clang::Stmt *stmt) const;

void *raw_pointer(const clang::Expr *expr) const;

mlir::Location location(const clang::Decl *decl) const override;

mlir::Location location(const clang::Stmt *stmt) const override;

mlir::Location location(const clang::Expr *expr) const override;

private:
uint64_t address_from_location(const std::string &str, char delimiter) const;

mlir::Location location(void *data, const clang::SourceLocation &loc) const;

clang::ASTContext *actx;

mlir::MLIRContext *mctx;
const LocationMap &locations;
};

} // namespace patchestry::codegen
31 changes: 31 additions & 0 deletions include/patchestry/Codegen/PassInstrumentation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024, Trail of Bits, Inc.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include <mlir/InitAllPasses.h>
#include <mlir/Pass/Pass.h>
#include <mlir/Pass/PassManager.h>
#include <mlir/Pass/PassRegistry.h>

namespace patchestry::codegen {

class PassInstrumentation : public mlir::PassInstrumentation
{
public:
explicit PassInstrumentation(bool enable_location_transform = false)
: location_transform(enable_location_transform) {}

void runAfterPass(mlir::Pass *pass, mlir::Operation *op) override;

void runBeforePass(mlir::Pass *pass, mlir::Operation *op) override;

private:
bool location_transform;
};

} // namespace patchestry::codegen
Loading
Loading