mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00:00
Codegen review changes (#18)
Co-authored-by: Jon Haslam <jonhaslam@meta.com>
This commit is contained in:
parent
1c3ee5bf6b
commit
3f2ae5e56f
@ -85,7 +85,7 @@ OICodeGen::OICodeGen(const Config &c) : config{c} {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config.membersToStub.reserve(typesToStub.size());
|
config.membersToStub.reserve(typesToStub.size());
|
||||||
for (auto &type : typesToStub) {
|
for (const auto &type : typesToStub) {
|
||||||
config.membersToStub.emplace_back(type, "*");
|
config.membersToStub.emplace_back(type, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,11 +102,7 @@ OICodeGen::OICodeGen(const Config &c) : config{c} {
|
|||||||
bool OICodeGen::registerContainer(const fs::path &path) {
|
bool OICodeGen::registerContainer(const fs::path &path) {
|
||||||
VLOG(1) << "registering container, path: " << path;
|
VLOG(1) << "registering container, path: " << path;
|
||||||
auto info = ContainerInfo::loadFromFile(path);
|
auto info = ContainerInfo::loadFromFile(path);
|
||||||
if (!info) {
|
if (!info || !funcGen.RegisterContainer(info->ctype, path)) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!funcGen.RegisterContainer(info->ctype, path)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +137,9 @@ bool OICodeGen::isKnownType(const std::string &type, std::string &matched) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<const std::string_view> OICodeGen::fullyQualifiedName(
|
std::optional<const std::string_view> OICodeGen::fullyQualifiedName(
|
||||||
struct drgn_type *type) {
|
drgn_type *type) {
|
||||||
auto entry = fullyQualifiedNames.find(type);
|
if (auto entry = fullyQualifiedNames.find(type);
|
||||||
if (entry != fullyQualifiedNames.end()) {
|
entry != fullyQualifiedNames.end()) {
|
||||||
return entry->second.contents;
|
return entry->second.contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,8 +155,7 @@ std::optional<const std::string_view> OICodeGen::fullyQualifiedName(
|
|||||||
return typeNamePair->second.contents;
|
return typeNamePair->second.contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ContainerInfo> OICodeGen::getContainerInfo(
|
std::optional<ContainerInfo> OICodeGen::getContainerInfo(drgn_type *type) {
|
||||||
struct drgn_type *type) {
|
|
||||||
auto name = fullyQualifiedName(type);
|
auto name = fullyQualifiedName(type);
|
||||||
if (!name.has_value()) {
|
if (!name.has_value()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -168,7 +163,7 @@ std::optional<ContainerInfo> OICodeGen::getContainerInfo(
|
|||||||
|
|
||||||
std::string nameStr = std::string(*name);
|
std::string nameStr = std::string(*name);
|
||||||
for (auto it = containerInfoList.rbegin(); it != containerInfoList.rend();
|
for (auto it = containerInfoList.rbegin(); it != containerInfoList.rend();
|
||||||
it++) {
|
++it) {
|
||||||
const auto &info = *it;
|
const auto &info = *it;
|
||||||
if (std::regex_search(nameStr, info->matcher)) {
|
if (std::regex_search(nameStr, info->matcher)) {
|
||||||
return *info;
|
return *info;
|
||||||
@ -177,12 +172,11 @@ std::optional<ContainerInfo> OICodeGen::getContainerInfo(
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::isContainer(struct drgn_type *type) {
|
bool OICodeGen::isContainer(drgn_type *type) {
|
||||||
return getContainerInfo(type).has_value();
|
return getContainerInfo(type).has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OICodeGen::preProcessUniquePtr(struct drgn_type *type,
|
std::string OICodeGen::preProcessUniquePtr(drgn_type *type, std::string name) {
|
||||||
std::string name) {
|
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
std::string deleterName;
|
std::string deleterName;
|
||||||
|
|
||||||
@ -322,7 +316,7 @@ void OICodeGen::replaceTemplateOperator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t comparatorSz = 1;
|
size_t comparatorSz = 1;
|
||||||
struct drgn_type *cmpType = template_params[index].first.type;
|
drgn_type *cmpType = template_params[index].first.type;
|
||||||
if (isDrgnSizeComplete(cmpType)) {
|
if (isDrgnSizeComplete(cmpType)) {
|
||||||
comparatorSz = drgn_type_size(cmpType);
|
comparatorSz = drgn_type_size(cmpType);
|
||||||
} else {
|
} else {
|
||||||
@ -350,7 +344,7 @@ void OICodeGen::replaceTemplateOperator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::replaceTemplateParameters(
|
void OICodeGen::replaceTemplateParameters(
|
||||||
struct drgn_type *type, TemplateParamList &template_params,
|
drgn_type *type, TemplateParamList &template_params,
|
||||||
std::vector<std::string> &template_params_strings,
|
std::vector<std::string> &template_params_strings,
|
||||||
const std::string &nameWithoutTemplate) {
|
const std::string &nameWithoutTemplate) {
|
||||||
auto containerInfo = getContainerInfo(type);
|
auto containerInfo = getContainerInfo(type);
|
||||||
@ -377,10 +371,10 @@ void OICodeGen::replaceTemplateParameters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::buildName(struct drgn_type *type, std::string &text,
|
bool OICodeGen::buildName(drgn_type *type, std::string &text,
|
||||||
std::string &outName) {
|
std::string &outName) {
|
||||||
int ptrDepth = 0;
|
int ptrDepth = 0;
|
||||||
struct drgn_type *ut = type;
|
drgn_type *ut = type;
|
||||||
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
||||||
ut = drgn_type_type(ut).type;
|
ut = drgn_type_type(ut).type;
|
||||||
ptrDepth++;
|
ptrDepth++;
|
||||||
@ -402,8 +396,7 @@ bool OICodeGen::buildName(struct drgn_type *type, std::string &text,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::buildNameInt(struct drgn_type *type,
|
bool OICodeGen::buildNameInt(drgn_type *type, std::string &nameWithoutTemplate,
|
||||||
std::string &nameWithoutTemplate,
|
|
||||||
std::string &outName) {
|
std::string &outName) {
|
||||||
// Calling buildName only makes sense if a type is a container and has
|
// Calling buildName only makes sense if a type is a container and has
|
||||||
// template parameters. For a generic template class, we just flatten the
|
// template parameters. For a generic template class, we just flatten the
|
||||||
@ -428,7 +421,7 @@ bool OICodeGen::buildNameInt(struct drgn_type *type,
|
|||||||
|
|
||||||
std::vector<std::string> templateParamsStrings;
|
std::vector<std::string> templateParamsStrings;
|
||||||
|
|
||||||
for (size_t i = 0; i < templateParams.size(); i++) {
|
for (size_t i = 0; i < templateParams.size(); ++i) {
|
||||||
auto &[p, value] = templateParams[i];
|
auto &[p, value] = templateParams[i];
|
||||||
enum drgn_qualifiers qualifiers = p.qualifiers;
|
enum drgn_qualifiers qualifiers = p.qualifiers;
|
||||||
prependQualifiers(qualifiers, outName);
|
prependQualifiers(qualifiers, outName);
|
||||||
@ -465,8 +458,7 @@ bool OICodeGen::buildNameInt(struct drgn_type *type,
|
|||||||
// matter for now.
|
// matter for now.
|
||||||
|
|
||||||
auto enumVal = std::stoull(value);
|
auto enumVal = std::stoull(value);
|
||||||
struct drgn_type_enumerator *enumerators =
|
drgn_type_enumerator *enumerators = drgn_type_enumerators(p.type);
|
||||||
drgn_type_enumerators(p.type);
|
|
||||||
templateParamName = *fullyQualifiedName(p.type);
|
templateParamName = *fullyQualifiedName(p.type);
|
||||||
templateParamName += "::";
|
templateParamName += "::";
|
||||||
templateParamName += enumerators[enumVal].name;
|
templateParamName += enumerators[enumVal].name;
|
||||||
@ -528,7 +520,7 @@ bool OICodeGen::buildNameInt(struct drgn_type *type,
|
|||||||
templateParamName = std::string("void");
|
templateParamName = std::string("void");
|
||||||
} 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;
|
||||||
struct drgn_type *arrayElementType = nullptr;
|
drgn_type *arrayElementType = nullptr;
|
||||||
getDrgnArrayElementType(p.type, &arrayElementType, elems);
|
getDrgnArrayElementType(p.type, &arrayElementType, elems);
|
||||||
|
|
||||||
if (drgn_type_has_name(arrayElementType)) {
|
if (drgn_type_has_name(arrayElementType)) {
|
||||||
@ -562,7 +554,7 @@ bool OICodeGen::buildNameInt(struct drgn_type *type,
|
|||||||
nameWithoutTemplate);
|
nameWithoutTemplate);
|
||||||
|
|
||||||
outName = nameWithoutTemplate;
|
outName = nameWithoutTemplate;
|
||||||
for (size_t i = 0; i < templateParamsStrings.size(); i++) {
|
for (size_t i = 0; i < templateParamsStrings.size(); ++i) {
|
||||||
auto &[p, value] = templateParams[i];
|
auto &[p, value] = templateParams[i];
|
||||||
enum drgn_qualifiers qualifiers = p.qualifiers;
|
enum drgn_qualifiers qualifiers = p.qualifiers;
|
||||||
prependQualifiers(qualifiers, outName);
|
prependQualifiers(qualifiers, outName);
|
||||||
@ -578,28 +570,29 @@ bool OICodeGen::buildNameInt(struct drgn_type *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::getTemplateParams(
|
bool OICodeGen::getTemplateParams(
|
||||||
struct drgn_type *type, size_t numTemplateParams,
|
drgn_type *type, size_t numTemplateParams,
|
||||||
std::vector<std::pair<struct drgn_qualified_type, std::string>> &v) {
|
std::vector<std::pair<drgn_qualified_type, std::string>> &v) {
|
||||||
struct drgn_type_template_parameter *tParams =
|
drgn_type_template_parameter *tParams = drgn_type_template_parameters(type);
|
||||||
drgn_type_template_parameters(type);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < numTemplateParams; i++) {
|
for (size_t i = 0; i < numTemplateParams; ++i) {
|
||||||
const struct drgn_object *obj = nullptr;
|
const drgn_object *obj = nullptr;
|
||||||
struct drgn_error *err = drgn_template_parameter_object(&tParams[i], &obj);
|
if (auto *err = drgn_template_parameter_object(&tParams[i], &obj);
|
||||||
if (err != nullptr) {
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
||||||
<< " " << err->message;
|
<< " " << err->message;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string value;
|
std::string value;
|
||||||
struct drgn_qualified_type t {};
|
drgn_qualified_type t{};
|
||||||
|
|
||||||
if (obj == nullptr) {
|
if (obj == nullptr) {
|
||||||
err = drgn_template_parameter_type(&tParams[i], &t);
|
if (auto *err = drgn_template_parameter_type(&tParams[i], &t);
|
||||||
if (err != nullptr) {
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
||||||
<< " " << err->message;
|
<< " " << err->message;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -634,8 +627,7 @@ bool OICodeGen::getTemplateParams(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OICodeGen::transformTypeName(struct drgn_type *type,
|
std::string OICodeGen::transformTypeName(drgn_type *type, std::string &text) {
|
||||||
std::string &text) {
|
|
||||||
VLOG(3) << "Original String " << text;
|
VLOG(3) << "Original String " << text;
|
||||||
|
|
||||||
std::string tmp = stripFullyQualifiedNameWithSeparators(text);
|
std::string tmp = stripFullyQualifiedNameWithSeparators(text);
|
||||||
@ -661,8 +653,7 @@ std::string OICodeGen::transformTypeName(struct drgn_type *type,
|
|||||||
return buildNameOutput;
|
return buildNameOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::getContainerTemplateParams(struct drgn_type *type,
|
bool OICodeGen::getContainerTemplateParams(drgn_type *type, bool &ifStub) {
|
||||||
bool &ifStub) {
|
|
||||||
if (containerTypeMapDrgn.find(type) != containerTypeMapDrgn.end()) {
|
if (containerTypeMapDrgn.find(type) != containerTypeMapDrgn.end()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -705,7 +696,7 @@ bool OICodeGen::getContainerTemplateParams(struct drgn_type *type,
|
|||||||
<< *numTemplateParams;
|
<< *numTemplateParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < *numTemplateParams; i++) {
|
for (size_t i = 0; i < *numTemplateParams; ++i) {
|
||||||
paramIdxs.push_back(i);
|
paramIdxs.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,7 +704,7 @@ bool OICodeGen::getContainerTemplateParams(struct drgn_type *type,
|
|||||||
return enumerateTemplateParamIdxs(type, *containerInfo, paramIdxs, ifStub);
|
return enumerateTemplateParamIdxs(type, *containerInfo, paramIdxs, ifStub);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateTemplateParamIdxs(struct drgn_type *type,
|
bool OICodeGen::enumerateTemplateParamIdxs(drgn_type *type,
|
||||||
const ContainerInfo &containerInfo,
|
const ContainerInfo &containerInfo,
|
||||||
const std::vector<size_t> ¶mIdxs,
|
const std::vector<size_t> ¶mIdxs,
|
||||||
bool &ifStub) {
|
bool &ifStub) {
|
||||||
@ -728,12 +719,11 @@ bool OICodeGen::enumerateTemplateParamIdxs(struct drgn_type *type,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_type_template_parameter *tParams =
|
drgn_type_template_parameter *tParams = drgn_type_template_parameters(type);
|
||||||
drgn_type_template_parameters(type);
|
|
||||||
for (auto i : paramIdxs) {
|
for (auto i : paramIdxs) {
|
||||||
struct drgn_qualified_type t;
|
drgn_qualified_type t{};
|
||||||
struct drgn_error *err = drgn_template_parameter_type(&tParams[i], &t);
|
if (auto *err = drgn_template_parameter_type(&tParams[i], &t);
|
||||||
if (err) {
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
||||||
<< " " << err->message;
|
<< " " << err->message;
|
||||||
return false;
|
return false;
|
||||||
@ -747,11 +737,12 @@ bool OICodeGen::enumerateTemplateParamIdxs(struct drgn_type *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto i : paramIdxs) {
|
for (auto i : paramIdxs) {
|
||||||
struct drgn_qualified_type t;
|
drgn_qualified_type t{};
|
||||||
struct drgn_error *err = drgn_template_parameter_type(&tParams[i], &t);
|
if (auto *err = drgn_template_parameter_type(&tParams[i], &t);
|
||||||
if (err) {
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
||||||
<< " " << err->message;
|
<< " " << err->message;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: This is painful, there seems to be a bug in drgn (or maybe it is
|
// TODO: This is painful, there seems to be a bug in drgn (or maybe it is
|
||||||
@ -772,7 +763,7 @@ bool OICodeGen::enumerateTemplateParamIdxs(struct drgn_type *type,
|
|||||||
// to `containerTypeMapDrgn`.
|
// to `containerTypeMapDrgn`.
|
||||||
if (containerInfo.ctype == SHRD_PTR_TYPE ||
|
if (containerInfo.ctype == SHRD_PTR_TYPE ||
|
||||||
containerInfo.ctype == UNIQ_PTR_TYPE) {
|
containerInfo.ctype == UNIQ_PTR_TYPE) {
|
||||||
struct drgn_qualified_type t {};
|
drgn_qualified_type t{};
|
||||||
// We checked that this succeeded in the previous loop
|
// We checked that this succeeded in the previous loop
|
||||||
drgn_template_parameter_type(&tParams[0], &t);
|
drgn_template_parameter_type(&tParams[0], &t);
|
||||||
if (drgn_type_kind(t.type) == DRGN_TYPE_VOID) {
|
if (drgn_type_kind(t.type) == DRGN_TYPE_VOID) {
|
||||||
@ -782,13 +773,13 @@ bool OICodeGen::enumerateTemplateParamIdxs(struct drgn_type *type,
|
|||||||
|
|
||||||
auto &templateTypes =
|
auto &templateTypes =
|
||||||
containerTypeMapDrgn
|
containerTypeMapDrgn
|
||||||
.emplace(type, std::pair(containerInfo,
|
.emplace(type,
|
||||||
std::vector<struct drgn_qualified_type>()))
|
std::pair(containerInfo, std::vector<drgn_qualified_type>()))
|
||||||
.first->second.second;
|
.first->second.second;
|
||||||
|
|
||||||
for (auto i : paramIdxs) {
|
for (auto i : paramIdxs) {
|
||||||
struct drgn_qualified_type t {};
|
drgn_qualified_type t{};
|
||||||
struct drgn_error *err = drgn_template_parameter_type(&tParams[i], &t);
|
drgn_error *err = drgn_template_parameter_type(&tParams[i], &t);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
LOG(ERROR) << "Error when looking up template parameter " << err->code
|
||||||
<< " " << err->message;
|
<< " " << err->message;
|
||||||
@ -803,13 +794,13 @@ bool OICodeGen::enumerateTemplateParamIdxs(struct drgn_type *type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::addPaddingForBaseClass(struct drgn_type *type,
|
void OICodeGen::addPaddingForBaseClass(drgn_type *type,
|
||||||
std::vector<std::string> &def) {
|
std::vector<std::string> &def) {
|
||||||
if (drgn_type_num_members(type) < 1) {
|
if (drgn_type_num_members(type) < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_type_member *members = drgn_type_members(type);
|
drgn_type_member *members = drgn_type_members(type);
|
||||||
|
|
||||||
VLOG(2) << "Base member offset is " << members[0].bit_offset / CHAR_BIT;
|
VLOG(2) << "Base member offset is " << members[0].bit_offset / CHAR_BIT;
|
||||||
|
|
||||||
@ -826,7 +817,7 @@ void OICodeGen::addPaddingForBaseClass(struct drgn_type *type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view OICodeGen::drgnKindStr(struct drgn_type *type) {
|
std::string_view OICodeGen::drgnKindStr(drgn_type *type) {
|
||||||
switch (drgn_type_kind(type)) {
|
switch (drgn_type_kind(type)) {
|
||||||
case DRGN_TYPE_VOID:
|
case DRGN_TYPE_VOID:
|
||||||
return "DRGN_TYPE_VOID";
|
return "DRGN_TYPE_VOID";
|
||||||
@ -856,8 +847,7 @@ std::string_view OICodeGen::drgnKindStr(struct drgn_type *type) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OICodeGen::getAnonName(struct drgn_type *type,
|
std::string OICodeGen::getAnonName(drgn_type *type, const char *template_) {
|
||||||
const char *template_) {
|
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
if (drgn_type_tag(type) != nullptr) {
|
if (drgn_type_tag(type) != nullptr) {
|
||||||
typeName = drgn_type_tag(type);
|
typeName = drgn_type_tag(type);
|
||||||
@ -881,7 +871,7 @@ std::string OICodeGen::getAnonName(struct drgn_type *type,
|
|||||||
return transformTypeName(type, typeName);
|
return transformTypeName(type, typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::getMemberDefinition(struct drgn_type *type) {
|
bool OICodeGen::getMemberDefinition(drgn_type *type) {
|
||||||
// Do a [] lookup to ensure `type` has a entry in classMembersMap
|
// Do a [] lookup to ensure `type` has a entry in classMembersMap
|
||||||
// If it has no entry, the lookup will default construct on for us
|
// If it has no entry, the lookup will default construct on for us
|
||||||
classMembersMap[type];
|
classMembersMap[type];
|
||||||
@ -897,15 +887,16 @@ bool OICodeGen::getMemberDefinition(struct drgn_type *type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_type_member *members = drgn_type_members(type);
|
drgn_type_member *members = drgn_type_members(type);
|
||||||
for (size_t i = 0; i < drgn_type_num_members(type); i++) {
|
for (size_t i = 0; i < drgn_type_num_members(type); ++i) {
|
||||||
auto &member = members[i];
|
auto &member = members[i];
|
||||||
auto memberName = member.name ? std::string(member.name)
|
auto memberName = member.name ? std::string(member.name)
|
||||||
: "__anon_member_" + std::to_string(i);
|
: "__anon_member_" + std::to_string(i);
|
||||||
|
|
||||||
struct drgn_qualified_type t {};
|
drgn_qualified_type t{};
|
||||||
uint64_t bitFieldSize = 0;
|
uint64_t bitFieldSize = 0;
|
||||||
if (auto *err = drgn_member_type(&member, &t, &bitFieldSize)) {
|
if (auto *err = drgn_member_type(&member, &t, &bitFieldSize);
|
||||||
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up member type '" << memberName
|
LOG(ERROR) << "Error when looking up member type '" << memberName
|
||||||
<< "': (" << err->code << ") " << err->message;
|
<< "': (" << err->code << ") " << err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
@ -945,13 +936,13 @@ void OICodeGen::printTypePath() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OICodeGen::typeToTransformedName(struct drgn_type *type) {
|
std::string OICodeGen::typeToTransformedName(drgn_type *type) {
|
||||||
auto typeName = typeToName(type);
|
auto typeName = typeToName(type);
|
||||||
typeName = transformTypeName(type, typeName);
|
typeName = transformTypeName(type, typeName);
|
||||||
return typeName;
|
return typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OICodeGen::typeToName(struct drgn_type *type) {
|
std::string OICodeGen::typeToName(drgn_type *type) {
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
if (drgn_type_has_tag(type)) {
|
if (drgn_type_has_tag(type)) {
|
||||||
const char *typeTag = drgn_type_tag(type);
|
const char *typeTag = drgn_type_tag(type);
|
||||||
@ -965,7 +956,7 @@ std::string OICodeGen::typeToName(struct drgn_type *type) {
|
|||||||
typeName = drgn_type_name(type);
|
typeName = drgn_type_name(type);
|
||||||
} else if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
|
} else if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
|
||||||
char *defStr = nullptr;
|
char *defStr = nullptr;
|
||||||
struct drgn_qualified_type qtype = {type, {}};
|
drgn_qualified_type qtype = {type, {}};
|
||||||
if (drgn_format_type_name(qtype, &defStr) != nullptr) {
|
if (drgn_format_type_name(qtype, &defStr) != nullptr) {
|
||||||
LOG(ERROR) << "Failed to get formatted string for " << type;
|
LOG(ERROR) << "Failed to get formatted string for " << type;
|
||||||
typeName = "";
|
typeName = "";
|
||||||
@ -977,7 +968,7 @@ std::string OICodeGen::typeToName(struct drgn_type *type) {
|
|||||||
return "void";
|
return "void";
|
||||||
} else if (drgn_type_kind(type) == DRGN_TYPE_ARRAY) {
|
} else if (drgn_type_kind(type) == DRGN_TYPE_ARRAY) {
|
||||||
size_t elems = 1;
|
size_t elems = 1;
|
||||||
struct drgn_type *arrayElementType = nullptr;
|
drgn_type *arrayElementType = nullptr;
|
||||||
getDrgnArrayElementType(type, &arrayElementType, elems);
|
getDrgnArrayElementType(type, &arrayElementType, elems);
|
||||||
|
|
||||||
if (drgn_type_has_name(arrayElementType)) {
|
if (drgn_type_has_name(arrayElementType)) {
|
||||||
@ -1011,7 +1002,7 @@ bool OICodeGen::populateDefsAndDecls() {
|
|||||||
auto *type = rootType.type;
|
auto *type = rootType.type;
|
||||||
rootTypeToIntrospect = rootType;
|
rootTypeToIntrospect = rootType;
|
||||||
|
|
||||||
struct drgn_qualified_type qtype {};
|
drgn_qualified_type qtype{};
|
||||||
if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
|
if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
|
||||||
qtype = drgn_type_type(type);
|
qtype = drgn_type_type(type);
|
||||||
type = qtype.type;
|
type = qtype.type;
|
||||||
@ -1035,9 +1026,9 @@ bool OICodeGen::populateDefsAndDecls() {
|
|||||||
return enumerateTypesRecurse(rootType.type);
|
return enumerateTypesRecurse(rootType.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uint64_t> OICodeGen::getDrgnTypeSize(struct drgn_type *type) {
|
std::optional<uint64_t> OICodeGen::getDrgnTypeSize(drgn_type *type) {
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
if (auto *err = drgn_type_sizeof(type, &sz)) {
|
if (auto *err = drgn_type_sizeof(type, &sz); err != nullptr) {
|
||||||
LOG(ERROR) << "dgn_type_sizeof(" << type << "): " << err->code << " "
|
LOG(ERROR) << "dgn_type_sizeof(" << type << "): " << err->code << " "
|
||||||
<< err->message;
|
<< err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
@ -1060,10 +1051,11 @@ std::optional<uint64_t> OICodeGen::getDrgnTypeSize(struct drgn_type *type) {
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::isDrgnSizeComplete(struct drgn_type *type) {
|
bool OICodeGen::isDrgnSizeComplete(drgn_type *type) {
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
auto *err = drgn_type_sizeof(type, &sz);
|
if (auto *err = drgn_type_sizeof(type, &sz); err != nullptr) {
|
||||||
if (err == nullptr) {
|
drgn_error_destroy(err);
|
||||||
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1081,7 +1073,7 @@ bool OICodeGen::isDrgnSizeComplete(struct drgn_type *type) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_type *OICodeGen::drgnUnderlyingType(struct drgn_type *type) {
|
drgn_type *OICodeGen::drgnUnderlyingType(drgn_type *type) {
|
||||||
auto *underlyingType = type;
|
auto *underlyingType = type;
|
||||||
|
|
||||||
while (drgn_type_kind(underlyingType) == DRGN_TYPE_TYPEDEF) {
|
while (drgn_type_kind(underlyingType) == DRGN_TYPE_TYPEDEF) {
|
||||||
@ -1091,14 +1083,15 @@ struct drgn_type *OICodeGen::drgnUnderlyingType(struct drgn_type *type) {
|
|||||||
return underlyingType;
|
return underlyingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateClassParents(struct drgn_type *type,
|
bool OICodeGen::enumerateClassParents(drgn_type *type,
|
||||||
const std::string &typeName) {
|
const std::string &typeName) {
|
||||||
struct drgn_type_template_parameter *parents = drgn_type_parents(type);
|
drgn_type_template_parameter *parents = drgn_type_parents(type);
|
||||||
|
|
||||||
for (size_t i = 0; i < drgn_type_num_parents(type); i++) {
|
for (size_t i = 0; i < drgn_type_num_parents(type); ++i) {
|
||||||
struct drgn_qualified_type t {};
|
drgn_qualified_type t{};
|
||||||
|
|
||||||
if (auto *err = drgn_template_parameter_type(&parents[i], &t)) {
|
if (auto *err = drgn_template_parameter_type(&parents[i], &t);
|
||||||
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up parent class for type " << type
|
LOG(ERROR) << "Error when looking up parent class for type " << type
|
||||||
<< " err " << err->code << " " << err->message;
|
<< " err " << err->code << " " << err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
@ -1125,13 +1118,13 @@ bool OICodeGen::enumerateClassParents(struct drgn_type *type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateClassMembers(struct drgn_type *type,
|
bool OICodeGen::enumerateClassMembers(drgn_type *type,
|
||||||
const std::string &typeName,
|
const std::string &typeName,
|
||||||
bool &isStubbed) {
|
bool &isStubbed) {
|
||||||
struct drgn_type_member *members = drgn_type_members(type);
|
drgn_type_member *members = drgn_type_members(type);
|
||||||
|
|
||||||
for (size_t i = 0; i < drgn_type_num_members(type); i++) {
|
for (size_t i = 0; i < drgn_type_num_members(type); ++i) {
|
||||||
struct drgn_qualified_type t {};
|
drgn_qualified_type t{};
|
||||||
auto *err = drgn_member_type(&members[i], &t, nullptr);
|
auto *err = drgn_member_type(&members[i], &t, nullptr);
|
||||||
|
|
||||||
if (err != nullptr || !isDrgnSizeComplete(t.type)) {
|
if (err != nullptr || !isDrgnSizeComplete(t.type)) {
|
||||||
@ -1151,10 +1144,12 @@ bool OICodeGen::enumerateClassMembers(struct drgn_type *type,
|
|||||||
memberName.assign(members[i].name);
|
memberName.assign(members[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (VLOG_IS_ON(2)) {
|
||||||
std::string outName;
|
std::string outName;
|
||||||
getDrgnTypeNameInt(t.type, outName);
|
getDrgnTypeNameInt(t.type, outName);
|
||||||
VLOG(2) << "Processing member; type: " << outName << " " << t.type
|
VLOG(2) << "Processing member; type: " << outName << " " << t.type
|
||||||
<< " name: " << memberName;
|
<< " name: " << memberName;
|
||||||
|
}
|
||||||
|
|
||||||
if (!OICodeGen::enumerateTypesRecurse(t.type)) {
|
if (!OICodeGen::enumerateTypesRecurse(t.type)) {
|
||||||
return false;
|
return false;
|
||||||
@ -1164,7 +1159,7 @@ bool OICodeGen::enumerateClassMembers(struct drgn_type *type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateClassTemplateParams(struct drgn_type *type,
|
bool OICodeGen::enumerateClassTemplateParams(drgn_type *type,
|
||||||
const std::string &typeName,
|
const std::string &typeName,
|
||||||
bool &isStubbed) {
|
bool &isStubbed) {
|
||||||
bool ifStub = false;
|
bool ifStub = false;
|
||||||
@ -1191,7 +1186,7 @@ bool OICodeGen::ifGenerateMemberDefinition(const std::string &typeName) {
|
|||||||
return !isKnownType(typeName);
|
return !isKnownType(typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::generateMemberDefinition(struct drgn_type *type,
|
bool OICodeGen::generateMemberDefinition(drgn_type *type,
|
||||||
std::string &typeName) {
|
std::string &typeName) {
|
||||||
if (!getMemberDefinition(type)) {
|
if (!getMemberDefinition(type)) {
|
||||||
return false;
|
return false;
|
||||||
@ -1207,9 +1202,9 @@ bool OICodeGen::generateMemberDefinition(struct drgn_type *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
auto *err = drgn_type_sizeof(type, &sz);
|
if (auto *err = drgn_type_sizeof(type, &sz); err != nullptr) {
|
||||||
if (err != nullptr) {
|
|
||||||
LOG(ERROR) << "Failed to get size: " << err->code << " " << err->message;
|
LOG(ERROR) << "Failed to get size: " << err->code << " " << err->message;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1236,8 +1231,7 @@ std::optional<std::string_view> OICodeGen::isTypeToStub(
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::isTypeToStub(struct drgn_type *type,
|
bool OICodeGen::isTypeToStub(drgn_type *type, const std::string &typeName) {
|
||||||
const std::string &typeName) {
|
|
||||||
if (isTypeToStub(typeName)) {
|
if (isTypeToStub(typeName)) {
|
||||||
VLOG(1) << "Found type to stub ";
|
VLOG(1) << "Found type to stub ";
|
||||||
knownDummyTypeList.insert(type);
|
knownDummyTypeList.insert(type);
|
||||||
@ -1247,13 +1241,13 @@ bool OICodeGen::isTypeToStub(struct drgn_type *type,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::isEmptyClassOrFunctionType(struct drgn_type *type,
|
bool OICodeGen::isEmptyClassOrFunctionType(drgn_type *type,
|
||||||
const std::string &typeName) {
|
const std::string &typeName) {
|
||||||
return (!isKnownType(typeName) && drgn_type_has_members(type) &&
|
return (!isKnownType(typeName) && drgn_type_has_members(type) &&
|
||||||
drgn_type_num_members(type) == 0);
|
drgn_type_num_members(type) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateClassType(struct drgn_type *type) {
|
bool OICodeGen::enumerateClassType(drgn_type *type) {
|
||||||
std::string typeName = getStructName(type);
|
std::string typeName = getStructName(type);
|
||||||
VLOG(2) << "Transformed typename: " << typeName << " " << type;
|
VLOG(2) << "Transformed typename: " << typeName << " " << type;
|
||||||
|
|
||||||
@ -1266,7 +1260,7 @@ bool OICodeGen::enumerateClassType(struct drgn_type *type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(isContainer(type) || isKnownType(typeName))) {
|
if (!isContainer(type)) {
|
||||||
if (!enumerateClassParents(type, typeName)) {
|
if (!enumerateClassParents(type, typeName)) {
|
||||||
knownDummyTypeList.insert(type);
|
knownDummyTypeList.insert(type);
|
||||||
return true;
|
return true;
|
||||||
@ -1308,7 +1302,7 @@ bool OICodeGen::enumerateClassType(struct drgn_type *type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateTypeDefType(struct drgn_type *type) {
|
bool OICodeGen::enumerateTypeDefType(drgn_type *type) {
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
if (drgn_type_has_name(type)) {
|
if (drgn_type_has_name(type)) {
|
||||||
typeName = drgn_type_name(type);
|
typeName = drgn_type_name(type);
|
||||||
@ -1346,10 +1340,10 @@ bool OICodeGen::enumerateTypeDefType(struct drgn_type *type) {
|
|||||||
tname = drgn_type_name(qtype.type);
|
tname = drgn_type_name(qtype.type);
|
||||||
} else {
|
} else {
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
auto *err = drgn_type_sizeof(type, &sz);
|
if (auto *err = drgn_type_sizeof(type, &sz); err != nullptr) {
|
||||||
if (err != nullptr) {
|
|
||||||
LOG(ERROR) << "Failed to get size: " << err->code << " " << err->message
|
LOG(ERROR) << "Failed to get size: " << err->code << " " << err->message
|
||||||
<< " " << typeName;
|
<< " " << typeName;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1368,7 +1362,7 @@ bool OICodeGen::enumerateTypeDefType(struct drgn_type *type) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateEnumType(struct drgn_type *type) {
|
bool OICodeGen::enumerateEnumType(drgn_type *type) {
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
|
|
||||||
if (drgn_type_tag(type) != nullptr) {
|
if (drgn_type_tag(type) != nullptr) {
|
||||||
@ -1394,8 +1388,8 @@ bool OICodeGen::enumerateEnumType(struct drgn_type *type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct drgn_type *getPtrUnderlyingType(struct drgn_type *type) {
|
static drgn_type *getPtrUnderlyingType(drgn_type *type) {
|
||||||
struct drgn_type *underlyingType = type;
|
drgn_type *underlyingType = type;
|
||||||
|
|
||||||
while (drgn_type_kind(underlyingType) == DRGN_TYPE_POINTER ||
|
while (drgn_type_kind(underlyingType) == DRGN_TYPE_POINTER ||
|
||||||
drgn_type_kind(underlyingType) == DRGN_TYPE_TYPEDEF) {
|
drgn_type_kind(underlyingType) == DRGN_TYPE_TYPEDEF) {
|
||||||
@ -1405,7 +1399,7 @@ static struct drgn_type *getPtrUnderlyingType(struct drgn_type *type) {
|
|||||||
return underlyingType;
|
return underlyingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumeratePointerType(struct drgn_type *type) {
|
bool OICodeGen::enumeratePointerType(drgn_type *type) {
|
||||||
// Not handling pointers right now. Pointer members in classes are going to be
|
// Not handling pointers right now. Pointer members in classes are going to be
|
||||||
// tricky. If we enumerate objects from pointers there are many questions :-
|
// tricky. If we enumerate objects from pointers there are many questions :-
|
||||||
// 1. How to handle uninitialized pointers
|
// 1. How to handle uninitialized pointers
|
||||||
@ -1416,14 +1410,13 @@ bool OICodeGen::enumeratePointerType(struct drgn_type *type) {
|
|||||||
// 4. Smart pointers might make it easier to detect (1)/(2)
|
// 4. Smart pointers might make it easier to detect (1)/(2)
|
||||||
|
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
struct drgn_qualified_type qtype = drgn_type_type(type);
|
drgn_qualified_type qtype = drgn_type_type(type);
|
||||||
|
|
||||||
funcDefTypeList.insert(type);
|
funcDefTypeList.insert(type);
|
||||||
|
|
||||||
// If type is a function pointer, directly store the underlying type in
|
// If type is a function pointer, directly store the underlying type in
|
||||||
// pointerToTypeMap, so that TreeBuilder can easily replace function
|
// pointerToTypeMap, so that TreeBuilder can easily replace function
|
||||||
// pointers with uintptr_t
|
// pointers with uintptr_t
|
||||||
struct drgn_type *utype = getPtrUnderlyingType(type);
|
drgn_type *utype = getPtrUnderlyingType(type);
|
||||||
if (drgn_type_kind(utype) == DRGN_TYPE_FUNCTION) {
|
if (drgn_type_kind(utype) == DRGN_TYPE_FUNCTION) {
|
||||||
VLOG(2) << "Type " << type << " is a function pointer to " << utype;
|
VLOG(2) << "Type " << type << " is a function pointer to " << utype;
|
||||||
pointerToTypeMap.emplace(type, utype);
|
pointerToTypeMap.emplace(type, utype);
|
||||||
@ -1431,7 +1424,7 @@ bool OICodeGen::enumeratePointerType(struct drgn_type *type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pointerToTypeMap.emplace(type, qtype.type);
|
pointerToTypeMap.emplace(type, qtype.type);
|
||||||
struct drgn_type *underlyingType = drgnUnderlyingType(qtype.type);
|
drgn_type *underlyingType = drgnUnderlyingType(qtype.type);
|
||||||
|
|
||||||
bool isComplete = isDrgnSizeComplete(underlyingType);
|
bool isComplete = isDrgnSizeComplete(underlyingType);
|
||||||
if (drgn_type_kind(underlyingType) == DRGN_TYPE_FUNCTION || isComplete) {
|
if (drgn_type_kind(underlyingType) == DRGN_TYPE_FUNCTION || isComplete) {
|
||||||
@ -1444,7 +1437,7 @@ bool OICodeGen::enumeratePointerType(struct drgn_type *type) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumeratePrimitiveType(struct drgn_type *type) {
|
bool OICodeGen::enumeratePrimitiveType(drgn_type *type) {
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
|
|
||||||
if (!drgn_type_has_name(type)) {
|
if (!drgn_type_has_name(type)) {
|
||||||
@ -1459,13 +1452,13 @@ bool OICodeGen::enumeratePrimitiveType(struct drgn_type *type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateArrayType(struct drgn_type *type) {
|
bool OICodeGen::enumerateArrayType(drgn_type *type) {
|
||||||
uint64_t ret = 0;
|
uint64_t ret = 0;
|
||||||
|
|
||||||
auto *err = drgn_type_sizeof(type, &ret);
|
if (auto *err = drgn_type_sizeof(type, &ret); err != nullptr) {
|
||||||
if (err != nullptr) {
|
|
||||||
LOG(ERROR) << "Error when looking up size from drgn " << err->code << " "
|
LOG(ERROR) << "Error when looking up size from drgn " << err->code << " "
|
||||||
<< err->message << " " << std::endl;
|
<< err->message << " " << std::endl;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1477,7 +1470,7 @@ bool OICodeGen::enumerateArrayType(struct drgn_type *type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateTypesRecurse(struct drgn_type *type) {
|
bool OICodeGen::enumerateTypesRecurse(drgn_type *type) {
|
||||||
auto kind = drgn_type_kind(type);
|
auto kind = drgn_type_kind(type);
|
||||||
|
|
||||||
if (kind == DRGN_TYPE_VOID || kind == DRGN_TYPE_FUNCTION) {
|
if (kind == DRGN_TYPE_VOID || kind == DRGN_TYPE_FUNCTION) {
|
||||||
@ -1494,7 +1487,7 @@ bool OICodeGen::enumerateTypesRecurse(struct drgn_type *type) {
|
|||||||
std::string outName;
|
std::string outName;
|
||||||
getDrgnTypeNameInt(type, outName);
|
getDrgnTypeNameInt(type, outName);
|
||||||
|
|
||||||
struct drgn_qualified_type qtype = {type, {}};
|
drgn_qualified_type qtype = {type, {}};
|
||||||
char *defStr = nullptr;
|
char *defStr = nullptr;
|
||||||
std::string typeDefStr;
|
std::string typeDefStr;
|
||||||
|
|
||||||
@ -1508,12 +1501,14 @@ bool OICodeGen::enumerateTypesRecurse(struct drgn_type *type) {
|
|||||||
|
|
||||||
VLOG(1) << "START processing type: " << outName << " " << type << " "
|
VLOG(1) << "START processing type: " << outName << " " << type << " "
|
||||||
<< drgnKindStr(type) << " {";
|
<< drgnKindStr(type) << " {";
|
||||||
|
|
||||||
g_level += 1;
|
g_level += 1;
|
||||||
|
|
||||||
VLOG(2) << typeDefStr;
|
|
||||||
|
|
||||||
typePath.push_back(type);
|
typePath.push_back(type);
|
||||||
|
|
||||||
|
if (VLOG_IS_ON(2)) {
|
||||||
|
VLOG(2) << "typeDefStr: " << typeDefStr;
|
||||||
printTypePath();
|
printTypePath();
|
||||||
|
}
|
||||||
|
|
||||||
processedTypes.insert(type);
|
processedTypes.insert(type);
|
||||||
|
|
||||||
@ -1557,7 +1552,7 @@ bool OICodeGen::enumerateTypesRecurse(struct drgn_type *type) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> OICodeGen::getNameForType(struct drgn_type *type) {
|
std::optional<std::string> OICodeGen::getNameForType(drgn_type *type) {
|
||||||
if (typeToNameMap.find(type) == typeToNameMap.end()) {
|
if (typeToNameMap.find(type) == typeToNameMap.end()) {
|
||||||
LOG(ERROR) << "QOO7 Failed to find " << type;
|
LOG(ERROR) << "QOO7 Failed to find " << type;
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -1566,7 +1561,7 @@ std::optional<std::string> OICodeGen::getNameForType(struct drgn_type *type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::getFuncDefClassMembers(
|
void OICodeGen::getFuncDefClassMembers(
|
||||||
std::string &code, struct drgn_type *type,
|
std::string &code, drgn_type *type,
|
||||||
std::unordered_map<std::string, int> &memberNames, bool skipPadding) {
|
std::unordered_map<std::string, int> &memberNames, bool skipPadding) {
|
||||||
if (drgn_type_kind(type) == DRGN_TYPE_TYPEDEF) {
|
if (drgn_type_kind(type) == DRGN_TYPE_TYPEDEF) {
|
||||||
// Handle case where parent is a typedef
|
// Handle case where parent is a typedef
|
||||||
@ -1590,7 +1585,7 @@ void OICodeGen::getFuncDefClassMembers(
|
|||||||
auto paddingIt = paddingIndexMap.find(type);
|
auto paddingIt = paddingIndexMap.find(type);
|
||||||
if (paddingIt != paddingIndexMap.end()) {
|
if (paddingIt != paddingIndexMap.end()) {
|
||||||
const auto &paddingRange = paddingIt->second;
|
const auto &paddingRange = paddingIt->second;
|
||||||
for (auto i = paddingRange.first; i < paddingRange.second; i++) {
|
for (auto i = paddingRange.first; i < paddingRange.second; ++i) {
|
||||||
code += "SAVE_SIZE(sizeof(t.__padding_" + std::to_string(i) + "));\n";
|
code += "SAVE_SIZE(sizeof(t.__padding_" + std::to_string(i) + "));\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1607,7 +1602,7 @@ void OICodeGen::getFuncDefClassMembers(
|
|||||||
code += ">;\n";
|
code += ">;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < members.size(); i++) {
|
for (std::size_t i = 0; i < members.size(); ++i) {
|
||||||
if (captureThriftIsset && i < members.size() - 1) {
|
if (captureThriftIsset && i < members.size() - 1) {
|
||||||
// Capture Thrift's isset value for each field, except __isset itself,
|
// Capture Thrift's isset value for each field, except __isset itself,
|
||||||
// which we assume comes last
|
// which we assume comes last
|
||||||
@ -1649,7 +1644,7 @@ void OICodeGen::getFuncDefClassMembers(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::getFuncDefinitionStr(std::string &code, struct drgn_type *type,
|
void OICodeGen::getFuncDefinitionStr(std::string &code, drgn_type *type,
|
||||||
const std::string &typeName) {
|
const std::string &typeName) {
|
||||||
if (classMembersMap.find(type) == classMembersMap.end()) {
|
if (classMembersMap.find(type) == classMembersMap.end()) {
|
||||||
return;
|
return;
|
||||||
@ -1730,7 +1725,7 @@ void OICodeGen::memberTransformName(
|
|||||||
}
|
}
|
||||||
|
|
||||||
OICodeGen::SortedTypeDefMap OICodeGen::getSortedTypeDefMap(
|
OICodeGen::SortedTypeDefMap OICodeGen::getSortedTypeDefMap(
|
||||||
const std::map<struct drgn_type *, struct drgn_type *> &typedefTypeMap) {
|
const std::map<drgn_type *, drgn_type *> &typedefTypeMap) {
|
||||||
auto typeMap = typedefTypeMap;
|
auto typeMap = typedefTypeMap;
|
||||||
SortedTypeDefMap typedefVec;
|
SortedTypeDefMap typedefVec;
|
||||||
|
|
||||||
@ -1747,7 +1742,7 @@ OICodeGen::SortedTypeDefMap OICodeGen::getSortedTypeDefMap(
|
|||||||
return typedefVec;
|
return typedefVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::getEnumUnderlyingTypeStr(struct drgn_type *e,
|
bool OICodeGen::getEnumUnderlyingTypeStr(drgn_type *e,
|
||||||
std::string &enumUnderlyingTypeStr) {
|
std::string &enumUnderlyingTypeStr) {
|
||||||
std::string name;
|
std::string name;
|
||||||
if (drgn_type_tag(e) != nullptr) {
|
if (drgn_type_tag(e) != nullptr) {
|
||||||
@ -1757,10 +1752,10 @@ bool OICodeGen::getEnumUnderlyingTypeStr(struct drgn_type *e,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
auto *err = drgn_type_sizeof(e, &sz);
|
if (auto *err = drgn_type_sizeof(e, &sz); err != nullptr) {
|
||||||
if (err != nullptr) {
|
|
||||||
LOG(ERROR) << "Error when looking up size from drgn " << err->code << " "
|
LOG(ERROR) << "Error when looking up size from drgn " << err->code << " "
|
||||||
<< err->message << " ";
|
<< err->message << " ";
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1787,8 +1782,7 @@ bool OICodeGen::getEnumUnderlyingTypeStr(struct drgn_type *e,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::getDrgnTypeNameInt(struct drgn_type *type,
|
bool OICodeGen::getDrgnTypeNameInt(drgn_type *type, std::string &outName) {
|
||||||
std::string &outName) {
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
if (drgn_type_kind(type) == DRGN_TYPE_ENUM) {
|
if (drgn_type_kind(type) == DRGN_TYPE_ENUM) {
|
||||||
@ -1808,14 +1802,14 @@ bool OICodeGen::getDrgnTypeNameInt(struct drgn_type *type,
|
|||||||
} else if (drgn_type_has_name(type)) {
|
} else if (drgn_type_has_name(type)) {
|
||||||
name.assign(drgn_type_name(type));
|
name.assign(drgn_type_name(type));
|
||||||
} else if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
|
} else if (drgn_type_kind(type) == DRGN_TYPE_POINTER) {
|
||||||
struct drgn_type *underlyingType = getPtrUnderlyingType(type);
|
drgn_type *underlyingType = getPtrUnderlyingType(type);
|
||||||
if (config.chaseRawPointers &&
|
if (config.chaseRawPointers &&
|
||||||
drgn_type_kind(underlyingType) != DRGN_TYPE_FUNCTION) {
|
drgn_type_kind(underlyingType) != DRGN_TYPE_FUNCTION) {
|
||||||
// For pointers, figure out name for the underlying type then add
|
// For pointers, figure out name for the underlying type then add
|
||||||
// appropriate number of '*'
|
// appropriate number of '*'
|
||||||
{
|
{
|
||||||
int ptrDepth = 0;
|
int ptrDepth = 0;
|
||||||
struct drgn_type *ut = type;
|
drgn_type *ut = type;
|
||||||
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
||||||
ut = drgn_type_type(ut).type;
|
ut = drgn_type_type(ut).type;
|
||||||
ptrDepth++;
|
ptrDepth++;
|
||||||
@ -1846,11 +1840,11 @@ bool OICodeGen::getDrgnTypeNameInt(struct drgn_type *type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::getDrgnTypeName(struct drgn_type *type, std::string &outName) {
|
bool OICodeGen::getDrgnTypeName(drgn_type *type, std::string &outName) {
|
||||||
return getDrgnTypeNameInt(type, outName);
|
return getDrgnTypeNameInt(type, outName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::addTypeToName(struct drgn_type *type, std::string name) {
|
void OICodeGen::addTypeToName(drgn_type *type, std::string name) {
|
||||||
VLOG(2) << "Trying to assign name to type: " << name << " " << type;
|
VLOG(2) << "Trying to assign name to type: " << name << " " << type;
|
||||||
|
|
||||||
if (typeToNameMap.find(type) != typeToNameMap.end()) {
|
if (typeToNameMap.find(type) != typeToNameMap.end()) {
|
||||||
@ -1893,7 +1887,7 @@ void OICodeGen::addTypeToName(struct drgn_type *type, std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::getClassMembersIncludingParent(
|
void OICodeGen::getClassMembersIncludingParent(
|
||||||
struct drgn_type *type, std::vector<DrgnClassMemberInfo> &out) {
|
drgn_type *type, std::vector<DrgnClassMemberInfo> &out) {
|
||||||
if (drgn_type_kind(type) == DRGN_TYPE_TYPEDEF) {
|
if (drgn_type_kind(type) == DRGN_TYPE_TYPEDEF) {
|
||||||
// Handle case where parent is a typedef
|
// Handle case where parent is a typedef
|
||||||
getClassMembersIncludingParent(drgnUnderlyingType(type), out);
|
getClassMembersIncludingParent(drgnUnderlyingType(type), out);
|
||||||
@ -1911,7 +1905,7 @@ void OICodeGen::getClassMembersIncludingParent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<struct drgn_type *, std::vector<DrgnClassMemberInfo>>
|
std::map<drgn_type *, std::vector<DrgnClassMemberInfo>>
|
||||||
&OICodeGen::getClassMembersMap() {
|
&OICodeGen::getClassMembersMap() {
|
||||||
for (auto &e : classMembersMap) {
|
for (auto &e : classMembersMap) {
|
||||||
std::vector<DrgnClassMemberInfo> v;
|
std::vector<DrgnClassMemberInfo> v;
|
||||||
@ -2017,7 +2011,7 @@ void OICodeGen::printAllTypeNames() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::generateStructDef(struct drgn_type *e, std::string &code) {
|
bool OICodeGen::generateStructDef(drgn_type *e, std::string &code) {
|
||||||
if (classMembersMap.find(e) == classMembersMap.end()) {
|
if (classMembersMap.find(e) == classMembersMap.end()) {
|
||||||
LOG(ERROR) << "Failed to find in classMembersMap " << e;
|
LOG(ERROR) << "Failed to find in classMembersMap " << e;
|
||||||
return false;
|
return false;
|
||||||
@ -2143,8 +2137,8 @@ bool OICodeGen::generateStructDef(struct drgn_type *e, std::string &code) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OICodeGen::getDrgnArrayElementType(struct drgn_type *type,
|
void OICodeGen::getDrgnArrayElementType(drgn_type *type,
|
||||||
struct drgn_type **outElemType,
|
drgn_type **outElemType,
|
||||||
size_t &outNumElems) {
|
size_t &outNumElems) {
|
||||||
size_t elems = 1;
|
size_t elems = 1;
|
||||||
|
|
||||||
@ -2161,7 +2155,7 @@ void OICodeGen::getDrgnArrayElementType(struct drgn_type *type,
|
|||||||
outNumElems = elems;
|
outNumElems = elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::isNumMemberGreaterThanZero(struct 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;
|
||||||
}
|
}
|
||||||
@ -2272,7 +2266,7 @@ std::optional<uint64_t> OICodeGen::generateMember(
|
|||||||
// TODO: No idea how to handle flexible array member or zero length array
|
// TODO: No idea how to handle flexible array member or zero length array
|
||||||
size_t elems = 1;
|
size_t elems = 1;
|
||||||
|
|
||||||
struct drgn_type *arrayElementType = nullptr;
|
drgn_type *arrayElementType = nullptr;
|
||||||
getDrgnArrayElementType(memberType, &arrayElementType, elems);
|
getDrgnArrayElementType(memberType, &arrayElementType, elems);
|
||||||
auto tmpStr = getNameForType(arrayElementType);
|
auto tmpStr = getNameForType(arrayElementType);
|
||||||
|
|
||||||
@ -2341,7 +2335,7 @@ std::optional<uint64_t> OICodeGen::generateMember(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::generateParent(
|
bool OICodeGen::generateParent(
|
||||||
struct drgn_type *p, std::unordered_map<std::string, int> &memberNames,
|
drgn_type *p, std::unordered_map<std::string, int> &memberNames,
|
||||||
uint64_t &currOffsetBits, std::string &code, size_t offsetToNextMember) {
|
uint64_t &currOffsetBits, std::string &code, size_t offsetToNextMember) {
|
||||||
// Parent class could be a typedef
|
// Parent class could be a typedef
|
||||||
PaddingInfo paddingInfo{};
|
PaddingInfo paddingInfo{};
|
||||||
@ -2372,8 +2366,7 @@ bool OICodeGen::generateParent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*Helper function that returns the alignment constraints in bits*/
|
/*Helper function that returns the alignment constraints in bits*/
|
||||||
std::optional<uint64_t> OICodeGen::getAlignmentRequirements(
|
std::optional<uint64_t> OICodeGen::getAlignmentRequirements(drgn_type *e) {
|
||||||
struct drgn_type *e) {
|
|
||||||
const uint64_t minimumAlignmentBits = CHAR_BIT;
|
const uint64_t minimumAlignmentBits = CHAR_BIT;
|
||||||
uint64_t alignmentRequirement = CHAR_BIT;
|
uint64_t alignmentRequirement = CHAR_BIT;
|
||||||
std::string outName;
|
std::string outName;
|
||||||
@ -2402,8 +2395,8 @@ std::optional<uint64_t> OICodeGen::getAlignmentRequirements(
|
|||||||
} else {
|
} else {
|
||||||
auto numMembers = drgn_type_num_members(e);
|
auto numMembers = drgn_type_num_members(e);
|
||||||
auto *members = drgn_type_members(e);
|
auto *members = drgn_type_members(e);
|
||||||
for (size_t i = 0; i < numMembers; i++) {
|
for (size_t i = 0; i < numMembers; ++i) {
|
||||||
struct drgn_qualified_type memberType {};
|
drgn_qualified_type memberType{};
|
||||||
if (drgn_member_type(&members[i], &memberType, nullptr) != nullptr) {
|
if (drgn_member_type(&members[i], &memberType, nullptr) != nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2414,7 +2407,7 @@ std::optional<uint64_t> OICodeGen::getAlignmentRequirements(
|
|||||||
std::max(alignmentRequirement, currentMemberAlignmentRequirement);
|
std::max(alignmentRequirement, currentMemberAlignmentRequirement);
|
||||||
}
|
}
|
||||||
for (size_t parentIndex = 0; parentIndex < parentClasses[e].size();
|
for (size_t parentIndex = 0; parentIndex < parentClasses[e].size();
|
||||||
parentIndex++) {
|
++parentIndex) {
|
||||||
size_t parentAlignment =
|
size_t parentAlignment =
|
||||||
getAlignmentRequirements(parentClasses[e][parentIndex].type)
|
getAlignmentRequirements(parentClasses[e][parentIndex].type)
|
||||||
.value_or(minimumAlignmentBits);
|
.value_or(minimumAlignmentBits);
|
||||||
@ -2435,7 +2428,7 @@ std::optional<uint64_t> OICodeGen::getAlignmentRequirements(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::generateStructMembers(
|
bool OICodeGen::generateStructMembers(
|
||||||
struct drgn_type *e, std::unordered_map<std::string, int> &memberNames,
|
drgn_type *e, std::unordered_map<std::string, int> &memberNames,
|
||||||
std::string &code, uint64_t &out_offset_bits, PaddingInfo &paddingInfo,
|
std::string &code, uint64_t &out_offset_bits, PaddingInfo &paddingInfo,
|
||||||
bool &violatesAlignmentRequirement, size_t offsetToNextMemberInSubclass) {
|
bool &violatesAlignmentRequirement, size_t offsetToNextMemberInSubclass) {
|
||||||
if (classMembersMap.find(e) == classMembersMap.end()) {
|
if (classMembersMap.find(e) == classMembersMap.end()) {
|
||||||
@ -2697,14 +2690,14 @@ bool OICodeGen::generateStructMembers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::generateStructDefs(std::string &code) {
|
bool OICodeGen::generateStructDefs(std::string &code) {
|
||||||
std::vector<struct drgn_type *> structDefTypeCopy = structDefType;
|
std::vector<drgn_type *> structDefTypeCopy = structDefType;
|
||||||
std::map<struct drgn_type *, std::vector<ParentMember>> parentClassesCopy =
|
std::map<drgn_type *, std::vector<ParentMember>> parentClassesCopy =
|
||||||
parentClasses;
|
parentClasses;
|
||||||
|
|
||||||
while (!structDefTypeCopy.empty()) {
|
while (!structDefTypeCopy.empty()) {
|
||||||
for (auto it = structDefTypeCopy.cbegin();
|
for (auto it = structDefTypeCopy.cbegin();
|
||||||
it != structDefTypeCopy.cend();) {
|
it != structDefTypeCopy.cend();) {
|
||||||
struct drgn_type *e = *it;
|
drgn_type *e = *it;
|
||||||
if (classMembersMap.find(e) == classMembersMap.end()) {
|
if (classMembersMap.find(e) == classMembersMap.end()) {
|
||||||
LOG(ERROR) << "Failed to find in classMembersMap " << e;
|
LOG(ERROR) << "Failed to find in classMembersMap " << e;
|
||||||
return false;
|
return false;
|
||||||
@ -2768,7 +2761,7 @@ bool OICodeGen::generateStructDefs(std::string &code) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::addStaticAssertsForType(struct drgn_type *type,
|
bool OICodeGen::addStaticAssertsForType(drgn_type *type,
|
||||||
bool generateAssertsForOffsets,
|
bool generateAssertsForOffsets,
|
||||||
std::string &code) {
|
std::string &code) {
|
||||||
auto struct_name = getNameForType(type);
|
auto struct_name = getNameForType(type);
|
||||||
@ -2962,8 +2955,10 @@ bool OICodeGen::generateJitCode(std::string &code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
if (auto *err = drgn_type_sizeof(e, &sz)) {
|
if (auto *err = drgn_type_sizeof(e, &sz); err != nullptr) {
|
||||||
|
bool shouldReturn = false;
|
||||||
std::string knownTypeName;
|
std::string knownTypeName;
|
||||||
|
|
||||||
if (auto opt = isTypeToStub(*typeName)) {
|
if (auto opt = isTypeToStub(*typeName)) {
|
||||||
knownTypeName = opt.value();
|
knownTypeName = opt.value();
|
||||||
}
|
}
|
||||||
@ -2976,6 +2971,12 @@ bool OICodeGen::generateJitCode(std::string &code) {
|
|||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Failed to get size: " << err->code << " " << err->message
|
LOG(ERROR) << "Failed to get size: " << err->code << " " << err->message
|
||||||
<< " " << e;
|
<< " " << e;
|
||||||
|
shouldReturn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
drgn_error_destroy(err);
|
||||||
|
|
||||||
|
if (shouldReturn) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3003,10 +3004,10 @@ bool OICodeGen::generateJitCode(std::string &code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t sz = 0;
|
uint64_t sz = 0;
|
||||||
auto *err = drgn_type_sizeof(e, &sz);
|
if (auto *err = drgn_type_sizeof(e, &sz); err != nullptr) {
|
||||||
if (err != nullptr) {
|
|
||||||
LOG(ERROR) << "Error when looking up size from drgn " << err->code << " "
|
LOG(ERROR) << "Error when looking up size from drgn " << err->code << " "
|
||||||
<< err->message << " ";
|
<< err->message << " ";
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3243,7 +3244,7 @@ bool OICodeGen::generateJitCode(std::string &code) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::isUnnamedStruct(struct drgn_type *type) {
|
bool OICodeGen::isUnnamedStruct(drgn_type *type) {
|
||||||
return unnamedUnion.find(type) != unnamedUnion.end();
|
return unnamedUnion.find(type) != unnamedUnion.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3379,7 +3380,7 @@ bool OICodeGen::generateNamesForTypes() {
|
|||||||
for (auto &e : funcDefTypeList) {
|
for (auto &e : funcDefTypeList) {
|
||||||
if (drgn_type_kind(e) == DRGN_TYPE_POINTER) {
|
if (drgn_type_kind(e) == DRGN_TYPE_POINTER) {
|
||||||
int ptrDepth = 0;
|
int ptrDepth = 0;
|
||||||
struct drgn_type *ut = e;
|
drgn_type *ut = e;
|
||||||
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
||||||
ut = drgn_type_type(ut).type;
|
ut = drgn_type_type(ut).type;
|
||||||
ptrDepth++;
|
ptrDepth++;
|
||||||
@ -3403,7 +3404,7 @@ bool OICodeGen::generateNamesForTypes() {
|
|||||||
for (auto &e : typedefTypes) {
|
for (auto &e : typedefTypes) {
|
||||||
if (drgn_type_kind(e.second) == DRGN_TYPE_POINTER) {
|
if (drgn_type_kind(e.second) == DRGN_TYPE_POINTER) {
|
||||||
int ptrDepth = 0;
|
int ptrDepth = 0;
|
||||||
struct drgn_type *ut = e.second;
|
drgn_type *ut = e.second;
|
||||||
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
while (drgn_type_kind(ut) == DRGN_TYPE_POINTER) {
|
||||||
ut = drgn_type_type(ut).type;
|
ut = drgn_type_type(ut).type;
|
||||||
ptrDepth++;
|
ptrDepth++;
|
||||||
@ -3471,10 +3472,11 @@ std::optional<RootInfo> OICodeGen::getRootType(SymbolService &symbols,
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_object global {};
|
drgn_object global{};
|
||||||
drgn_object_init(&global, prog);
|
drgn_object_init(&global, prog);
|
||||||
if (auto *err = drgn_program_find_object(prog, req.func.c_str(), nullptr,
|
if (auto *err = drgn_program_find_object(prog, req.func.c_str(), nullptr,
|
||||||
DRGN_FIND_OBJECT_ANY, &global)) {
|
DRGN_FIND_OBJECT_ANY, &global);
|
||||||
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Failed to lookup global variable '" << req.func
|
LOG(ERROR) << "Failed to lookup global variable '" << req.func
|
||||||
<< "': " << err->code << " " << err->message;
|
<< "': " << err->code << " " << err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
@ -3502,9 +3504,10 @@ std::optional<RootInfo> OICodeGen::getRootType(SymbolService &symbols,
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_qualified_type ft {};
|
drgn_qualified_type ft{};
|
||||||
if (auto *err = drgn_program_find_type_by_symbol_name(
|
if (auto *err = drgn_program_find_type_by_symbol_name(prog, req.func.c_str(),
|
||||||
prog, req.func.c_str(), &ft, nullptr, nullptr)) {
|
&ft, nullptr, nullptr);
|
||||||
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when finding type by symbol " << err->code << " "
|
LOG(ERROR) << "Error when finding type by symbol " << err->code << " "
|
||||||
<< err->message;
|
<< err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
@ -3547,9 +3550,9 @@ std::optional<RootInfo> OICodeGen::getRootType(SymbolService &symbols,
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_qualified_type paramType {};
|
drgn_qualified_type paramType{};
|
||||||
auto *err = drgn_parameter_type(¶ms[argIdx], ¶mType);
|
if (auto *err = drgn_parameter_type(¶ms[argIdx], ¶mType);
|
||||||
if (err != nullptr) {
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Failed to get params: " << err->code << " " << err->message;
|
LOG(ERROR) << "Failed to get params: " << err->code << " " << err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -3568,7 +3571,7 @@ std::optional<RootInfo> OICodeGen::getRootType(SymbolService &symbols,
|
|||||||
* Generate static_asserts for the offsets of each member of the given type
|
* Generate static_asserts for the offsets of each member of the given type
|
||||||
*/
|
*/
|
||||||
bool OICodeGen::staticAssertMemberOffsets(
|
bool OICodeGen::staticAssertMemberOffsets(
|
||||||
const std::string &struct_name, struct drgn_type *struct_type,
|
const std::string &struct_name, drgn_type *struct_type,
|
||||||
std::string &assert_str, std::unordered_map<std::string, int> &memberNames,
|
std::string &assert_str, std::unordered_map<std::string, int> &memberNames,
|
||||||
uint64_t base_offset) {
|
uint64_t base_offset) {
|
||||||
if (knownDummyTypeList.find(struct_type) != knownDummyTypeList.end()) {
|
if (knownDummyTypeList.find(struct_type) != knownDummyTypeList.end()) {
|
||||||
@ -3604,7 +3607,7 @@ bool OICodeGen::staticAssertMemberOffsets(
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto *members = drgn_type_members(struct_type);
|
auto *members = drgn_type_members(struct_type);
|
||||||
for (size_t i = 0; i < drgn_type_num_members(struct_type); i++) {
|
for (size_t i = 0; i < drgn_type_num_members(struct_type); ++i) {
|
||||||
if (members[i].name == nullptr) {
|
if (members[i].name == nullptr) {
|
||||||
// Types can be defined in a class without assigning a member name e.g.
|
// Types can be defined in a class without assigning a member name e.g.
|
||||||
// struct A { struct {int i;} ;}; is a valid struct with size 4.
|
// struct A { struct {int i;} ;}; is a valid struct with size 4.
|
||||||
@ -3615,12 +3618,14 @@ bool OICodeGen::staticAssertMemberOffsets(
|
|||||||
|
|
||||||
std::replace(memberName.begin(), memberName.end(), '.', '_');
|
std::replace(memberName.begin(), memberName.end(), '.', '_');
|
||||||
|
|
||||||
struct drgn_qualified_type memberQualType {};
|
drgn_qualified_type memberQualType{};
|
||||||
uint64_t bitFieldSize = 0;
|
uint64_t bitFieldSize = 0;
|
||||||
auto *err = drgn_member_type(&members[i], &memberQualType, &bitFieldSize);
|
if (auto *err =
|
||||||
if (err != nullptr) {
|
drgn_member_type(&members[i], &memberQualType, &bitFieldSize);
|
||||||
|
err != nullptr) {
|
||||||
LOG(ERROR) << "Error when looking up member type " << err->code << " "
|
LOG(ERROR) << "Error when looking up member type " << err->code << " "
|
||||||
<< err->message << " " << memberName;
|
<< err->message << " " << memberName;
|
||||||
|
drgn_error_destroy(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3643,11 +3648,11 @@ std::map<std::string, PaddingInfo> OICodeGen::getPaddingInfo() {
|
|||||||
return paddedStructs;
|
return paddedStructs;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drgn_qualified_type OICodeGen::getRootType() {
|
drgn_qualified_type OICodeGen::getRootType() {
|
||||||
return rootTypeToIntrospect;
|
return rootTypeToIntrospect;
|
||||||
};
|
};
|
||||||
|
|
||||||
void OICodeGen::setRootType(struct drgn_qualified_type rt) {
|
void OICodeGen::setRootType(drgn_qualified_type rt) {
|
||||||
rootType = rt;
|
rootType = rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
184
src/OICodeGen.h
184
src/OICodeGen.h
@ -38,7 +38,7 @@ extern "C" {
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
struct ParentMember {
|
struct ParentMember {
|
||||||
struct drgn_type *type;
|
drgn_type *type;
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
|
|
||||||
bool operator<(const ParentMember &parent) const {
|
bool operator<(const ParentMember &parent) const {
|
||||||
@ -89,84 +89,77 @@ class OICodeGen {
|
|||||||
// TODO: remove me once all the callsites are gone
|
// TODO: remove me once all the callsites are gone
|
||||||
static void initializeCodeGen();
|
static void initializeCodeGen();
|
||||||
|
|
||||||
struct drgn_qualified_type getRootType();
|
drgn_qualified_type getRootType();
|
||||||
void setRootType(struct drgn_qualified_type rt);
|
void setRootType(drgn_qualified_type rt);
|
||||||
void setLinkageName(std::string name) {
|
void setLinkageName(std::string name) {
|
||||||
linkageName = name;
|
linkageName = name;
|
||||||
};
|
};
|
||||||
TypeHierarchy getTypeHierarchy();
|
TypeHierarchy getTypeHierarchy();
|
||||||
std::map<std::string, PaddingInfo> getPaddingInfo();
|
std::map<std::string, PaddingInfo> getPaddingInfo();
|
||||||
|
|
||||||
static void getDrgnArrayElementType(struct drgn_type *type,
|
static void getDrgnArrayElementType(drgn_type *type, drgn_type **outElemType,
|
||||||
struct drgn_type **outElemType,
|
|
||||||
size_t &outNumElems);
|
size_t &outNumElems);
|
||||||
|
|
||||||
bool isContainer(struct drgn_type *type);
|
bool isContainer(drgn_type *type);
|
||||||
|
|
||||||
static struct drgn_type *drgnUnderlyingType(struct drgn_type *type);
|
static drgn_type *drgnUnderlyingType(drgn_type *type);
|
||||||
|
|
||||||
bool buildName(struct drgn_type *type, std::string &text,
|
bool buildName(drgn_type *type, std::string &text, std::string &outName);
|
||||||
std::string &outName);
|
|
||||||
|
|
||||||
std::string typeToTransformedName(struct drgn_type *type);
|
std::string typeToTransformedName(drgn_type *type);
|
||||||
static std::string typeToName(struct drgn_type *type);
|
static std::string typeToName(drgn_type *type);
|
||||||
|
|
||||||
bool enumerateTypesRecurse(struct drgn_type *type);
|
bool enumerateTypesRecurse(drgn_type *type);
|
||||||
static std::string_view drgnKindStr(struct drgn_type *type);
|
static std::string_view drgnKindStr(drgn_type *type);
|
||||||
std::set<struct drgn_type *> processedTypes;
|
std::set<drgn_type *> processedTypes;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config config{};
|
Config config{};
|
||||||
FuncGen funcGen;
|
FuncGen funcGen;
|
||||||
|
|
||||||
using ContainerTypeMap =
|
using ContainerTypeMap =
|
||||||
std::pair<ContainerInfo, std::vector<struct drgn_qualified_type>>;
|
std::pair<ContainerInfo, std::vector<drgn_qualified_type>>;
|
||||||
|
|
||||||
using TemplateParamList =
|
using TemplateParamList =
|
||||||
std::vector<std::pair<struct drgn_qualified_type, std::string>>;
|
std::vector<std::pair<drgn_qualified_type, std::string>>;
|
||||||
|
|
||||||
using SortedTypeDefMap =
|
using SortedTypeDefMap = std::vector<std::pair<drgn_type *, drgn_type *>>;
|
||||||
std::vector<std::pair<struct drgn_type *, struct drgn_type *>>;
|
|
||||||
|
|
||||||
std::string rootTypeStr;
|
std::string rootTypeStr;
|
||||||
std::string linkageName;
|
std::string linkageName;
|
||||||
std::map<struct drgn_type *, std::string> unnamedUnion;
|
std::map<drgn_type *, std::string> unnamedUnion;
|
||||||
std::map<std::string, size_t> sizeMap;
|
std::map<std::string, size_t> sizeMap;
|
||||||
std::map<struct drgn_type *, ContainerTypeMap> containerTypeMapDrgn;
|
std::map<drgn_type *, ContainerTypeMap> containerTypeMapDrgn;
|
||||||
std::vector<std::unique_ptr<ContainerInfo>> containerInfoList;
|
std::vector<std::unique_ptr<ContainerInfo>> containerInfoList;
|
||||||
std::vector<struct drgn_type *> enumTypes;
|
std::vector<drgn_type *> enumTypes;
|
||||||
std::vector<struct drgn_type *> typePath;
|
std::vector<drgn_type *> typePath;
|
||||||
std::vector<std::string> knownTypes;
|
std::vector<std::string> knownTypes;
|
||||||
struct drgn_qualified_type rootType;
|
drgn_qualified_type rootType;
|
||||||
struct drgn_qualified_type rootTypeToIntrospect;
|
drgn_qualified_type rootTypeToIntrospect;
|
||||||
|
|
||||||
std::map<std::string, std::string> typedefMap;
|
std::map<std::string, std::string> typedefMap;
|
||||||
std::map<struct drgn_type *, std::vector<ParentMember>> parentClasses;
|
std::map<drgn_type *, std::vector<ParentMember>> parentClasses;
|
||||||
|
|
||||||
size_t pad_index = 0;
|
size_t pad_index = 0;
|
||||||
std::unordered_map<struct drgn_type *, std::pair<size_t, size_t>>
|
std::unordered_map<drgn_type *, std::pair<size_t, size_t>> paddingIndexMap;
|
||||||
paddingIndexMap;
|
|
||||||
|
|
||||||
std::map<struct drgn_type *, struct drgn_type *> typedefTypes;
|
std::map<drgn_type *, drgn_type *> typedefTypes;
|
||||||
std::map<struct drgn_type *, std::vector<DrgnClassMemberInfo>>
|
std::map<drgn_type *, std::vector<DrgnClassMemberInfo>> classMembersMap;
|
||||||
classMembersMap;
|
std::map<drgn_type *, std::vector<DrgnClassMemberInfo>> classMembersMapCopy;
|
||||||
std::map<struct drgn_type *, std::vector<DrgnClassMemberInfo>>
|
std::map<drgn_type *, std::string> typeToNameMap;
|
||||||
classMembersMapCopy;
|
std::map<std::string, drgn_type *> nameToTypeMap;
|
||||||
std::map<struct drgn_type *, std::string> typeToNameMap;
|
std::set<drgn_type *> funcDefTypeList;
|
||||||
std::map<std::string, struct drgn_type *> nameToTypeMap;
|
std::vector<drgn_type *> structDefType;
|
||||||
std::set<struct drgn_type *> funcDefTypeList;
|
std::set<drgn_type *> knownDummyTypeList;
|
||||||
std::vector<struct drgn_type *> structDefType;
|
std::map<drgn_type *, drgn_type *> pointerToTypeMap;
|
||||||
std::set<struct drgn_type *> knownDummyTypeList;
|
std::set<drgn_type *> thriftIssetStructTypes;
|
||||||
std::map<struct drgn_type *, struct drgn_type *> pointerToTypeMap;
|
std::vector<drgn_type *> topoSortedStructTypes;
|
||||||
std::set<struct drgn_type *> thriftIssetStructTypes;
|
|
||||||
std::vector<struct drgn_type *> topoSortedStructTypes;
|
|
||||||
|
|
||||||
std::set<ContainerInfo> containerTypesFuncDef;
|
std::set<ContainerInfo> containerTypesFuncDef;
|
||||||
|
|
||||||
std::map<std::string, PaddingInfo> paddedStructs;
|
std::map<std::string, PaddingInfo> paddedStructs;
|
||||||
|
|
||||||
std::map<struct drgn_type *, std::vector<DrgnClassMemberInfo>>
|
std::map<drgn_type *, std::vector<DrgnClassMemberInfo>> &getClassMembersMap();
|
||||||
&getClassMembersMap();
|
|
||||||
|
|
||||||
class DrgnString {
|
class DrgnString {
|
||||||
struct FreeDeleter {
|
struct FreeDeleter {
|
||||||
@ -193,54 +186,52 @@ class OICodeGen {
|
|||||||
const std::string &fullyQualifiedname);
|
const std::string &fullyQualifiedname);
|
||||||
static void removeTemplateParamAtIndex(std::vector<std::string> ¶ms,
|
static void removeTemplateParamAtIndex(std::vector<std::string> ¶ms,
|
||||||
const size_t index);
|
const size_t index);
|
||||||
std::unordered_map<struct drgn_type *, DrgnString> fullyQualifiedNames;
|
std::unordered_map<drgn_type *, DrgnString> fullyQualifiedNames;
|
||||||
std::optional<const std::string_view> fullyQualifiedName(
|
std::optional<const std::string_view> fullyQualifiedName(drgn_type *type);
|
||||||
struct drgn_type *type);
|
|
||||||
static SortedTypeDefMap getSortedTypeDefMap(
|
static SortedTypeDefMap getSortedTypeDefMap(
|
||||||
const std::map<struct drgn_type *, struct drgn_type *> &typedefTypeMap);
|
const std::map<drgn_type *, drgn_type *> &typedefTypeMap);
|
||||||
|
|
||||||
std::optional<ContainerInfo> getContainerInfo(struct drgn_type *type);
|
std::optional<ContainerInfo> getContainerInfo(drgn_type *type);
|
||||||
void printAllTypes();
|
void printAllTypes();
|
||||||
void printAllTypeNames();
|
void printAllTypeNames();
|
||||||
void printTypePath();
|
void printTypePath();
|
||||||
|
|
||||||
static void addPaddingForBaseClass(struct drgn_type *type,
|
static void addPaddingForBaseClass(drgn_type *type,
|
||||||
std::vector<std::string> &def);
|
std::vector<std::string> &def);
|
||||||
void addTypeToName(struct drgn_type *type, std::string name);
|
void addTypeToName(drgn_type *type, std::string name);
|
||||||
bool generateNamesForTypes();
|
bool generateNamesForTypes();
|
||||||
bool generateJitCode(std::string &code);
|
bool generateJitCode(std::string &code);
|
||||||
bool generateStructDefs(std::string &code);
|
bool generateStructDefs(std::string &code);
|
||||||
bool generateStructDef(struct drgn_type *e, std::string &code);
|
bool generateStructDef(drgn_type *e, std::string &code);
|
||||||
bool getDrgnTypeName(struct drgn_type *type, std::string &outName);
|
bool getDrgnTypeName(drgn_type *type, std::string &outName);
|
||||||
|
|
||||||
bool getDrgnTypeNameInt(struct drgn_type *type, std::string &outName);
|
bool getDrgnTypeNameInt(drgn_type *type, std::string &outName);
|
||||||
bool populateDefsAndDecls();
|
bool populateDefsAndDecls();
|
||||||
static void memberTransformName(
|
static void memberTransformName(
|
||||||
std::map<std::string, std::string> &templateTransformMap,
|
std::map<std::string, std::string> &templateTransformMap,
|
||||||
std::string &typeName);
|
std::string &typeName);
|
||||||
|
|
||||||
bool getMemberDefinition(struct drgn_type *type);
|
bool getMemberDefinition(drgn_type *type);
|
||||||
bool isKnownType(const std::string &type);
|
bool isKnownType(const std::string &type);
|
||||||
bool isKnownType(const std::string &type, std::string &matched);
|
bool isKnownType(const std::string &type, std::string &matched);
|
||||||
|
|
||||||
static bool getTemplateParams(
|
static bool getTemplateParams(
|
||||||
struct drgn_type *type, size_t numTemplateParams,
|
drgn_type *type, size_t numTemplateParams,
|
||||||
std::vector<std::pair<struct drgn_qualified_type, std::string>> &v);
|
std::vector<std::pair<drgn_qualified_type, std::string>> &v);
|
||||||
|
|
||||||
bool enumerateTemplateParamIdxs(struct drgn_type *type,
|
bool enumerateTemplateParamIdxs(drgn_type *type,
|
||||||
const ContainerInfo &containerInfo,
|
const ContainerInfo &containerInfo,
|
||||||
const std::vector<size_t> ¶mIdxs,
|
const std::vector<size_t> ¶mIdxs,
|
||||||
bool &ifStub);
|
bool &ifStub);
|
||||||
bool getContainerTemplateParams(struct drgn_type *type, bool &ifStub);
|
bool getContainerTemplateParams(drgn_type *type, bool &ifStub);
|
||||||
void getFuncDefinitionStr(std::string &code, struct drgn_type *type,
|
void getFuncDefinitionStr(std::string &code, drgn_type *type,
|
||||||
const std::string &typeName);
|
const std::string &typeName);
|
||||||
std::optional<uint64_t> getDrgnTypeSize(struct drgn_type *type);
|
std::optional<uint64_t> getDrgnTypeSize(drgn_type *type);
|
||||||
|
|
||||||
std::optional<std::string> getNameForType(struct drgn_type *type);
|
std::optional<std::string> getNameForType(drgn_type *type);
|
||||||
|
|
||||||
static std::string preProcessUniquePtr(struct drgn_type *type,
|
static std::string preProcessUniquePtr(drgn_type *type, std::string name);
|
||||||
std::string name);
|
std::string transformTypeName(drgn_type *type, std::string &text);
|
||||||
std::string transformTypeName(struct drgn_type *type, std::string &text);
|
|
||||||
static std::string templateTransformType(const std::string &typeName);
|
static std::string templateTransformType(const std::string &typeName);
|
||||||
static std::string structNameTransformType(const std::string &typeName);
|
static std::string structNameTransformType(const std::string &typeName);
|
||||||
|
|
||||||
@ -252,81 +243,76 @@ class OICodeGen {
|
|||||||
const DrgnClassMemberInfo &m,
|
const DrgnClassMemberInfo &m,
|
||||||
std::unordered_map<std::string, int> &memberNames,
|
std::unordered_map<std::string, int> &memberNames,
|
||||||
uint64_t currOffsetBits, std::string &code, bool isInUnion);
|
uint64_t currOffsetBits, std::string &code, bool isInUnion);
|
||||||
bool generateParent(struct drgn_type *p,
|
bool generateParent(drgn_type *p,
|
||||||
std::unordered_map<std::string, int> &memberNames,
|
std::unordered_map<std::string, int> &memberNames,
|
||||||
uint64_t &currOffsetBits, std::string &code,
|
uint64_t &currOffsetBits, std::string &code,
|
||||||
size_t offsetToNextMember);
|
size_t offsetToNextMember);
|
||||||
std::optional<uint64_t> getAlignmentRequirements(struct drgn_type *e);
|
std::optional<uint64_t> getAlignmentRequirements(drgn_type *e);
|
||||||
bool generateStructMembers(struct drgn_type *e,
|
bool generateStructMembers(drgn_type *e,
|
||||||
std::unordered_map<std::string, int> &memberNames,
|
std::unordered_map<std::string, int> &memberNames,
|
||||||
std::string &code, uint64_t &out_offset_bits,
|
std::string &code, uint64_t &out_offset_bits,
|
||||||
PaddingInfo &paddingInfo,
|
PaddingInfo &paddingInfo,
|
||||||
bool &violatesAlignmentRequirement,
|
bool &violatesAlignmentRequirement,
|
||||||
size_t offsetToNextMember);
|
size_t offsetToNextMember);
|
||||||
void getFuncDefClassMembers(std::string &code, struct drgn_type *type,
|
void getFuncDefClassMembers(std::string &code, drgn_type *type,
|
||||||
std::unordered_map<std::string, int> &memberNames,
|
std::unordered_map<std::string, int> &memberNames,
|
||||||
bool skipPadding = false);
|
bool skipPadding = false);
|
||||||
bool isDrgnSizeComplete(struct drgn_type *type);
|
bool isDrgnSizeComplete(drgn_type *type);
|
||||||
|
|
||||||
static bool getEnumUnderlyingTypeStr(struct drgn_type *e,
|
static bool getEnumUnderlyingTypeStr(drgn_type *e,
|
||||||
std::string &enumUnderlyingTypeStr);
|
std::string &enumUnderlyingTypeStr);
|
||||||
|
|
||||||
bool ifEnumerateClass(const std::string &typeName);
|
bool ifEnumerateClass(const std::string &typeName);
|
||||||
|
|
||||||
bool enumerateClassParents(struct drgn_type *type,
|
bool enumerateClassParents(drgn_type *type, const std::string &typeName);
|
||||||
const std::string &typeName);
|
bool enumerateClassMembers(drgn_type *type, const std::string &typeName,
|
||||||
bool enumerateClassMembers(struct drgn_type *type,
|
bool &isStubbed);
|
||||||
const std::string &typeName, bool &isStubbed);
|
bool enumerateClassTemplateParams(drgn_type *type,
|
||||||
bool enumerateClassTemplateParams(struct drgn_type *type,
|
|
||||||
const std::string &typeName,
|
const std::string &typeName,
|
||||||
bool &isStubbed);
|
bool &isStubbed);
|
||||||
bool ifGenerateMemberDefinition(const std::string &typeName);
|
bool ifGenerateMemberDefinition(const std::string &typeName);
|
||||||
bool generateMemberDefinition(struct drgn_type *type, std::string &typeName);
|
bool generateMemberDefinition(drgn_type *type, std::string &typeName);
|
||||||
std::optional<std::pair<std::string_view, std::string_view>> isMemberToStub(
|
std::optional<std::pair<std::string_view, std::string_view>> isMemberToStub(
|
||||||
const std::string &type, const std::string &member);
|
const std::string &type, const std::string &member);
|
||||||
std::optional<std::string_view> isTypeToStub(const std::string &typeName);
|
std::optional<std::string_view> isTypeToStub(const std::string &typeName);
|
||||||
bool isTypeToStub(struct drgn_type *type, const std::string &typeName);
|
bool isTypeToStub(drgn_type *type, const std::string &typeName);
|
||||||
bool isEmptyClassOrFunctionType(struct drgn_type *type,
|
bool isEmptyClassOrFunctionType(drgn_type *type, const std::string &typeName);
|
||||||
const std::string &typeName);
|
bool enumerateClassType(drgn_type *type);
|
||||||
bool enumerateClassType(struct drgn_type *type);
|
bool enumerateTypeDefType(drgn_type *type);
|
||||||
bool enumerateTypeDefType(struct drgn_type *type);
|
bool enumerateEnumType(drgn_type *type);
|
||||||
bool enumerateEnumType(struct drgn_type *type);
|
bool enumeratePointerType(drgn_type *type);
|
||||||
bool enumeratePointerType(struct drgn_type *type);
|
bool enumeratePrimitiveType(drgn_type *type);
|
||||||
bool enumeratePrimitiveType(struct drgn_type *type);
|
bool enumerateArrayType(drgn_type *type);
|
||||||
bool enumerateArrayType(struct drgn_type *type);
|
|
||||||
|
|
||||||
bool isUnnamedStruct(struct drgn_type *type);
|
bool isUnnamedStruct(drgn_type *type);
|
||||||
|
|
||||||
std::string getAnonName(struct drgn_type *, const char *);
|
std::string getAnonName(drgn_type *, const char *);
|
||||||
std::string getStructName(struct drgn_type *type) {
|
std::string getStructName(drgn_type *type) {
|
||||||
return getAnonName(type, "__anon_struct_");
|
return getAnonName(type, "__anon_struct_");
|
||||||
}
|
}
|
||||||
std::string getUnionName(struct drgn_type *type) {
|
std::string getUnionName(drgn_type *type) {
|
||||||
return getAnonName(type, "__anon_union_");
|
return getAnonName(type, "__anon_union_");
|
||||||
}
|
}
|
||||||
static void declareThriftStruct(std::string &code, std::string_view name);
|
static void declareThriftStruct(std::string &code, std::string_view name);
|
||||||
|
|
||||||
bool isNumMemberGreaterThanZero(struct drgn_type *type);
|
bool isNumMemberGreaterThanZero(drgn_type *type);
|
||||||
void getClassMembersIncludingParent(struct drgn_type *type,
|
void getClassMembersIncludingParent(drgn_type *type,
|
||||||
std::vector<DrgnClassMemberInfo> &out);
|
std::vector<DrgnClassMemberInfo> &out);
|
||||||
bool staticAssertMemberOffsets(
|
bool staticAssertMemberOffsets(
|
||||||
const std::string &struct_name, struct drgn_type *struct_type,
|
const std::string &struct_name, drgn_type *struct_type,
|
||||||
std::string &assert_str,
|
std::string &assert_str,
|
||||||
std::unordered_map<std::string, int> &member_names,
|
std::unordered_map<std::string, int> &member_names,
|
||||||
uint64_t base_offset = 0);
|
uint64_t base_offset = 0);
|
||||||
bool addStaticAssertsForType(struct drgn_type *type,
|
bool addStaticAssertsForType(drgn_type *type, bool generateAssertsForOffsets,
|
||||||
bool generateAssertsForOffsets,
|
|
||||||
std::string &code);
|
std::string &code);
|
||||||
bool buildNameInt(struct drgn_type *type, std::string &nameWithoutTemplate,
|
bool buildNameInt(drgn_type *type, std::string &nameWithoutTemplate,
|
||||||
std::string &outName);
|
std::string &outName);
|
||||||
void replaceTemplateOperator(
|
void replaceTemplateOperator(
|
||||||
std::vector<std::pair<struct drgn_qualified_type, std::string>>
|
std::vector<std::pair<drgn_qualified_type, std::string>> &template_params,
|
||||||
&template_params,
|
|
||||||
std::vector<std::string> &template_params_strings, size_t index);
|
std::vector<std::string> &template_params_strings, size_t index);
|
||||||
void replaceTemplateParameters(
|
void replaceTemplateParameters(
|
||||||
struct drgn_type *type,
|
drgn_type *type,
|
||||||
std::vector<std::pair<struct drgn_qualified_type, std::string>>
|
std::vector<std::pair<drgn_qualified_type, std::string>> &template_params,
|
||||||
&template_params,
|
|
||||||
std::vector<std::string> &template_params_strings,
|
std::vector<std::string> &template_params_strings,
|
||||||
const std::string &nameWithoutTemplate);
|
const std::string &nameWithoutTemplate);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user