Split codegen into separate build targets

To help with the transition to type-graph based CodeGen, we need to
reduce dependencies on legacy CodeGen from other parts of OI.

Pieces of CodeGen referenced by other files, but which only return
drgn data have been moved into a new "drgn_utils" target, allowing
us to remove CodeGen dependencies for these functions.

The new "symbol_service" build target can be used in the future by
other files only needing access to symbol information and not full
CodeGen.
This commit is contained in:
Alastair Robertson 2023-02-17 07:16:25 -08:00 committed by Alastair Robertson
parent 53ba312f1e
commit ccc90c3068
10 changed files with 144 additions and 85 deletions

View File

@ -224,19 +224,17 @@ add_library(oid_parser STATIC ${BISON_Parser_OUTPUTS} ${FLEX_Lexer_OUTPUTS})
target_link_libraries(oid_parser glog::glog) target_link_libraries(oid_parser glog::glog)
### Core OI ### Core OI
add_subdirectory(src)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
add_library(oicore add_library(oicore
src/ContainerInfo.cpp
src/Descs.cpp src/Descs.cpp
src/FuncGen.cpp
src/Metrics.cpp src/Metrics.cpp
src/OICache.cpp src/OICache.cpp
src/OICodeGen.cpp
src/OICompiler.cpp src/OICompiler.cpp
src/OIUtils.cpp src/OIUtils.cpp
src/PaddingHunter.cpp src/PaddingHunter.cpp
src/Serialize.cpp src/Serialize.cpp
src/SymbolService.cpp
) )
add_dependencies(oicore libdrgn) add_dependencies(oicore libdrgn)
set_project_warnings(oicore) set_project_warnings(oicore)
@ -245,10 +243,11 @@ target_compile_definitions(oicore PRIVATE ${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(llvm_libs core native mcjit x86disassembler) llvm_map_components_to_libnames(llvm_libs core native mcjit x86disassembler)
target_link_libraries(oicore target_link_libraries(oicore
codegen
${Boost_LIBRARIES} ${Boost_LIBRARIES}
Boost::headers Boost::headers
glog::glog glog::glog
tomlplusplus::tomlplusplus
) )
if (FORCE_LLVM_STATIC) if (FORCE_LLVM_STATIC)
target_link_libraries(oicore target_link_libraries(oicore
@ -296,9 +295,11 @@ target_link_libraries(oil oicore)
add_executable(oilgen add_executable(oilgen
tools/OILGen.cpp tools/OILGen.cpp
src/OIGenerator.cpp src/OIGenerator.cpp
src/DrgnUtils.cpp
) )
target_link_libraries(oilgen oicore) target_link_libraries(oilgen
drgn_utils
oicore
)
### Object Introspection cache Printer (OIP) ### Object Introspection cache Printer (OIP)
add_executable(oip tools/OIP.cpp) add_executable(oip tools/OIP.cpp)

36
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,36 @@
add_library(drgn_utils DrgnUtils.cpp)
target_link_libraries(drgn_utils
glog::glog
"-L${DRGN_PATH}/.libs"
drgn
)
add_dependencies(drgn_utils libdrgn)
add_library(symbol_service
Descs.cpp
SymbolService.cpp
)
target_link_libraries(symbol_service
drgn_utils
Boost::headers
${Boost_LIBRARIES}
glog::glog
dw
)
add_library(codegen
ContainerInfo.cpp
FuncGen.cpp
OICodeGen.cpp
)
target_link_libraries(codegen
symbol_service
Boost::headers
${Boost_LIBRARIES}
glog::glog
tomlplusplus::tomlplusplus
)

View File

@ -16,6 +16,8 @@
#include "DrgnUtils.h" #include "DrgnUtils.h"
#include <glog/logging.h>
extern "C" { extern "C" {
#include <drgn.h> #include <drgn.h>
} }
@ -93,3 +95,68 @@ const char* symbol::name(drgn_symbol* sym) {
} }
} // namespace drgnplusplus } // namespace drgnplusplus
namespace drgn_utils {
void getDrgnArrayElementType(drgn_type* type, drgn_type** outElemType,
size_t& outNumElems) {
size_t elems = 1;
// for multi dimensional arrays
auto* arrayElementType = type;
while (drgn_type_kind(arrayElementType) == DRGN_TYPE_ARRAY) {
size_t l = drgn_type_length(arrayElementType);
elems *= l;
auto qtype = drgn_type_type(arrayElementType);
arrayElementType = qtype.type;
}
*outElemType = arrayElementType;
outNumElems = elems;
}
std::string typeToName(drgn_type* type) {
std::string typeName;
if (drgn_type_has_tag(type)) {
const char* typeTag = drgn_type_tag(type);
if (typeTag != nullptr) {
typeName = typeTag;
} else {
typeName = type->_private.oi_name;
}
// TODO: Lookup unnamed union in type->string flag
} else if (drgn_type_has_name(type)) {
typeName = drgn_type_name(type);
} else if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
char* defStr = nullptr;
drgn_qualified_type qtype = {type, {}};
if (drgn_format_type_name(qtype, &defStr) != nullptr) {
LOG(ERROR) << "Failed to get formatted string for " << type;
typeName = "";
} else {
typeName.assign(defStr);
free(defStr);
}
} else if (drgn_type_kind(type) == DRGN_TYPE_VOID) {
return "void";
} else if (drgn_type_kind(type) == DRGN_TYPE_ARRAY) {
size_t elems = 1;
drgn_type* arrayElementType = nullptr;
getDrgnArrayElementType(type, &arrayElementType, elems);
if (drgn_type_has_name(arrayElementType)) {
typeName = drgn_type_name(arrayElementType);
} else if (drgn_type_has_tag(arrayElementType)) {
typeName = drgn_type_tag(arrayElementType);
} else {
LOG(ERROR) << "Failed4 to get typename ";
return "";
}
} else {
LOG(ERROR) << "Failed3 to get typename ";
return "";
}
return typeName;
}
} // namespace drgn_utils

View File

@ -31,6 +31,7 @@ struct drgn_func_iterator;
struct drgn_program; struct drgn_program;
struct drgn_qualified_type; struct drgn_qualified_type;
struct drgn_symbol; struct drgn_symbol;
struct drgn_type;
} }
namespace drgnplusplus { namespace drgnplusplus {
@ -125,3 +126,19 @@ const char* name(drgn_symbol*);
} }
} // namespace drgnplusplus } // namespace drgnplusplus
namespace drgn_utils {
/*
* These utils are not intended to be permanent. As part of the transition to
* type-graph based CodeGen, we need to break dependencies on legacy OICodeGen
* from other parts of OI.
*
* Parts of OICodeGen used by other parts of OI, but which only return drgn
* data can be moved here.
*/
void getDrgnArrayElementType(drgn_type* type, drgn_type** outElemType,
size_t& outNumElems);
std::string typeToName(drgn_type* type);
} // namespace drgn_utils

View File

@ -31,6 +31,7 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include "DrgnUtils.h"
#include "FuncGen.h" #include "FuncGen.h"
#include "OIParser.h" #include "OIParser.h"
#include "PaddingHunter.h" #include "PaddingHunter.h"
@ -532,7 +533,7 @@ bool OICodeGen::buildNameInt(drgn_type *type, std::string &nameWithoutTemplate,
} else if (drgn_type_kind(p.type) == DRGN_TYPE_ARRAY) { } else if (drgn_type_kind(p.type) == DRGN_TYPE_ARRAY) {
size_t elems = 1; size_t elems = 1;
drgn_type *arrayElementType = nullptr; drgn_type *arrayElementType = nullptr;
getDrgnArrayElementType(p.type, &arrayElementType, elems); drgn_utils::getDrgnArrayElementType(p.type, &arrayElementType, elems);
if (drgn_type_has_name(arrayElementType)) { if (drgn_type_has_name(arrayElementType)) {
templateParamName = drgn_type_name(arrayElementType); templateParamName = drgn_type_name(arrayElementType);
@ -927,55 +928,11 @@ bool OICodeGen::getMemberDefinition(drgn_type *type) {
} }
std::string OICodeGen::typeToTransformedName(drgn_type *type) { std::string OICodeGen::typeToTransformedName(drgn_type *type) {
auto typeName = typeToName(type); auto typeName = drgn_utils::typeToName(type);
typeName = transformTypeName(type, typeName); typeName = transformTypeName(type, typeName);
return typeName; return typeName;
} }
std::string OICodeGen::typeToName(drgn_type *type) {
std::string typeName;
if (drgn_type_has_tag(type)) {
const char *typeTag = drgn_type_tag(type);
if (typeTag != nullptr) {
typeName = typeTag;
} else {
typeName = type->_private.oi_name;
}
// TODO: Lookup unnamed union in type->string flag
} else if (drgn_type_has_name(type)) {
typeName = drgn_type_name(type);
} else if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
char *defStr = nullptr;
drgn_qualified_type qtype = {type, {}};
if (drgn_format_type_name(qtype, &defStr) != nullptr) {
LOG(ERROR) << "Failed to get formatted string for " << type;
typeName = "";
} else {
typeName.assign(defStr);
free(defStr);
}
} else if (drgn_type_kind(type) == DRGN_TYPE_VOID) {
return "void";
} else if (drgn_type_kind(type) == DRGN_TYPE_ARRAY) {
size_t elems = 1;
drgn_type *arrayElementType = nullptr;
getDrgnArrayElementType(type, &arrayElementType, elems);
if (drgn_type_has_name(arrayElementType)) {
typeName = drgn_type_name(arrayElementType);
} else if (drgn_type_has_tag(arrayElementType)) {
typeName = drgn_type_tag(arrayElementType);
} else {
LOG(ERROR) << "Failed4 to get typename ";
return "";
}
} else {
LOG(ERROR) << "Failed3 to get typename ";
return "";
}
return typeName;
}
bool OICodeGen::recordChildren(drgn_type *type) { bool OICodeGen::recordChildren(drgn_type *type) {
drgn_type_template_parameter *parents = drgn_type_parents(type); drgn_type_template_parameter *parents = drgn_type_parents(type);
@ -2365,24 +2322,6 @@ bool OICodeGen::generateStructDef(drgn_type *e, std::string &code) {
return true; return true;
} }
void OICodeGen::getDrgnArrayElementType(drgn_type *type,
drgn_type **outElemType,
size_t &outNumElems) {
size_t elems = 1;
// for multi dimensional arrays
auto *arrayElementType = type;
while (drgn_type_kind(arrayElementType) == DRGN_TYPE_ARRAY) {
size_t l = drgn_type_length(arrayElementType);
elems *= l;
auto qtype = drgn_type_type(arrayElementType);
arrayElementType = qtype.type;
}
*outElemType = arrayElementType;
outNumElems = elems;
}
bool OICodeGen::isNumMemberGreaterThanZero(drgn_type *type) { bool OICodeGen::isNumMemberGreaterThanZero(drgn_type *type) {
if (drgn_type_num_members(type) > 0) { if (drgn_type_num_members(type) > 0) {
return true; return true;
@ -2495,7 +2434,7 @@ std::optional<uint64_t> OICodeGen::generateMember(
size_t elems = 1; size_t elems = 1;
drgn_type *arrayElementType = nullptr; drgn_type *arrayElementType = nullptr;
getDrgnArrayElementType(memberType, &arrayElementType, elems); drgn_utils::getDrgnArrayElementType(memberType, &arrayElementType, elems);
auto tmpStr = getNameForType(arrayElementType); auto tmpStr = getNameForType(arrayElementType);
if (!tmpStr.has_value()) { if (!tmpStr.has_value()) {
@ -3416,7 +3355,7 @@ bool OICodeGen::generateJitCode(std::string &code) {
/* Start function definitions. First define top level func for root object /* Start function definitions. First define top level func for root object
*/ */
auto rawTypeName = typeToName(type); auto rawTypeName = drgn_utils::typeToName(type);
if (config.useDataSegment) { if (config.useDataSegment) {
if (rootTypeStr.starts_with("unique_ptr") || if (rootTypeStr.starts_with("unique_ptr") ||
rootTypeStr.starts_with("LowPtr") || rootTypeStr.starts_with("LowPtr") ||

View File

@ -97,9 +97,6 @@ class OICodeGen {
TypeHierarchy getTypeHierarchy(); TypeHierarchy getTypeHierarchy();
std::map<std::string, PaddingInfo> getPaddingInfo(); std::map<std::string, PaddingInfo> getPaddingInfo();
static void getDrgnArrayElementType(drgn_type *type, drgn_type **outElemType,
size_t &outNumElems);
bool isContainer(drgn_type *type); bool isContainer(drgn_type *type);
static drgn_type *drgnUnderlyingType(drgn_type *type); static drgn_type *drgnUnderlyingType(drgn_type *type);
@ -107,7 +104,6 @@ class OICodeGen {
bool buildName(drgn_type *type, std::string &text, std::string &outName); bool buildName(drgn_type *type, std::string &text, std::string &outName);
std::string typeToTransformedName(drgn_type *type); std::string typeToTransformedName(drgn_type *type);
static std::string typeToName(drgn_type *type);
bool enumerateTypesRecurse(drgn_type *type); bool enumerateTypesRecurse(drgn_type *type);
static std::string_view drgnKindStr(drgn_type *type); static std::string_view drgnKindStr(drgn_type *type);

View File

@ -19,7 +19,9 @@
#include "OICompiler.h" #include "OICompiler.h"
namespace OIUtils { namespace OIUtils {
bool processConfigFile(const std::string& configFilePath, bool processConfigFile(const std::string& configFilePath,
OICompiler::Config& compilerConfig, OICompiler::Config& compilerConfig,
OICodeGen::Config& generatorConfig); OICodeGen::Config& generatorConfig);
}
} // namespace OIUtils

View File

@ -20,7 +20,7 @@
#include <boost/serialization/version.hpp> #include <boost/serialization/version.hpp>
#include <stdexcept> #include <stdexcept>
#include "OICodeGen.h" #include "DrgnUtils.h"
namespace boost::serialization { namespace boost::serialization {
@ -319,7 +319,7 @@ void serialize(Archive &ar, struct drgn_type &type,
// `serialize_c_string`. // `serialize_c_string`.
std::string oi_name; std::string oi_name;
if (Archive::is_saving::value) { if (Archive::is_saving::value) {
oi_name = OICodeGen::typeToName(&type); oi_name = drgn_utils::typeToName(&type);
type._private.oi_name = oi_name.c_str(); type._private.oi_name = oi_name.c_str();
} }
serialize_c_string(ar, const_cast<char **>(&type._private.oi_name)); serialize_c_string(ar, const_cast<char **>(&type._private.oi_name));

View File

@ -23,7 +23,7 @@
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include "OICodeGen.h" #include "DrgnUtils.h"
#include "OIParser.h" #include "OIParser.h"
extern "C" { extern "C" {
@ -733,7 +733,7 @@ std::string SymbolService::getTypeName(struct drgn_type *type) {
if (drgn_type_kind(type) == DRGN_TYPE_POINTER) { if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
type = drgn_type_type(type).type; type = drgn_type_type(type).type;
} }
return OICodeGen::typeToName(type); return drgn_utils::typeToName(type);
} }
std::optional<RootInfo> SymbolService::getRootType(const irequest &req) { std::optional<RootInfo> SymbolService::getRootType(const irequest &req) {

View File

@ -26,6 +26,7 @@
#include <stdexcept> #include <stdexcept>
#include "ContainerInfo.h" #include "ContainerInfo.h"
#include "DrgnUtils.h"
#include "Metrics.h" #include "Metrics.h"
#include "OICodeGen.h" #include "OICodeGen.h"
#include "PaddingHunter.h" #include "PaddingHunter.h"
@ -275,7 +276,7 @@ void TreeBuilder::setPaddedStructs(
static std::string drgnTypeToName(struct drgn_type *type) { static std::string drgnTypeToName(struct drgn_type *type) {
if (type->_private.program != nullptr) { if (type->_private.program != nullptr) {
return OICodeGen::typeToName(type); return drgn_utils::typeToName(type);
} }
return type->_private.oi_name ? type->_private.oi_name : ""; return type->_private.oi_name ? type->_private.oi_name : "";
@ -531,8 +532,8 @@ void TreeBuilder::processContainer(const Variable &variable, Node &node) {
kind = ARRAY_TYPE; kind = ARRAY_TYPE;
struct drgn_type *arrayElementType = nullptr; struct drgn_type *arrayElementType = nullptr;
size_t numElems = 0; size_t numElems = 0;
OICodeGen::getDrgnArrayElementType(variable.type, &arrayElementType, drgn_utils::getDrgnArrayElementType(variable.type, &arrayElementType,
numElems); numElems);
assert(numElems > 0); assert(numElems > 0);
elementTypes.push_back( elementTypes.push_back(
drgn_qualified_type{arrayElementType, (enum drgn_qualifiers)(0)}); drgn_qualified_type{arrayElementType, (enum drgn_qualifiers)(0)});