mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-12 21:56:54 +00:00
oil: switch to using an impl function with no default implementation (#46)
This commit is contained in:
parent
6f786b4348
commit
8956ca5522
@ -111,7 +111,7 @@ class OILibrary {
|
||||
OILibrary(void *TemplateFunc, options opt);
|
||||
~OILibrary();
|
||||
int init();
|
||||
int getObjectSize(void *ObjectAddr, size_t &size);
|
||||
int getObjectSize(void *objectAddr, size_t &size);
|
||||
|
||||
options opts;
|
||||
|
||||
@ -141,17 +141,17 @@ class CodegenHandler {
|
||||
delete lib;
|
||||
}
|
||||
|
||||
static int getObjectSize(const T &ObjectAddr, size_t &ObjectSize) {
|
||||
static int getObjectSize(const T &objectAddr, size_t &objectSize) {
|
||||
OILibrary *lib;
|
||||
if (int responseCode = getLibrary(lib);
|
||||
responseCode != Response::OIL_SUCCESS) {
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
return lib->getObjectSize((void *)&ObjectAddr, ObjectSize);
|
||||
return lib->getObjectSize((void *)&objectAddr, objectSize);
|
||||
}
|
||||
|
||||
static int getObjectSize(const T &ObjectAddr, size_t &ObjectSize,
|
||||
static int getObjectSize(const T &objectAddr, size_t &objectSize,
|
||||
const options &opts, bool checkOptions = true) {
|
||||
OILibrary *lib;
|
||||
if (int responseCode = getLibrary(lib, opts, checkOptions);
|
||||
@ -159,7 +159,7 @@ class CodegenHandler {
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
return lib->getObjectSize((void *)&ObjectAddr, ObjectSize);
|
||||
return lib->getObjectSize((void *)&objectAddr, objectSize);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -230,12 +230,18 @@ class CodegenHandler {
|
||||
* Ahead-Of-Time (AOT) compilation.
|
||||
*/
|
||||
template <class T>
|
||||
int getObjectSize(const T &ObjectAddr, size_t &ObjectSize, const options &opts,
|
||||
int getObjectSize(const T &objectAddr, size_t &objectSize, const options &opts,
|
||||
bool checkOptions = true) {
|
||||
return CodegenHandler<T>::getObjectSize(ObjectAddr, ObjectSize, opts,
|
||||
return CodegenHandler<T>::getObjectSize(objectAddr, objectSize, opts,
|
||||
checkOptions);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
int __attribute__((weak))
|
||||
getObjectSizeImpl(const T &objectAddr, size_t &objectSize);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -248,12 +254,14 @@ int getObjectSize(const T &ObjectAddr, size_t &ObjectSize, const options &opts,
|
||||
* production system.
|
||||
*/
|
||||
template <class T>
|
||||
int __attribute__((weak))
|
||||
getObjectSize(const T &ObjectAddr, size_t &ObjectSize) {
|
||||
int getObjectSize(const T &objectAddr, size_t &objectSize) {
|
||||
#ifdef OIL_AOT_COMPILATION
|
||||
return Response::OIL_UNINITIALISED;
|
||||
if (!getObjectSizeImpl<T>) {
|
||||
return Response::OIL_UNINITIALISED;
|
||||
}
|
||||
return getObjectSizeImpl(objectAddr, objectSize);
|
||||
#else
|
||||
return CodegenHandler<T>::getObjectSize(ObjectAddr, ObjectSize);
|
||||
return CodegenHandler<T>::getObjectSize(objectAddr, objectSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -69,4 +69,27 @@ func_iterator& func_iterator::operator++() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SymbolsDeleter::operator()(std::span<drgn_symbol*>* syms) noexcept {
|
||||
drgn_symbols_destroy(syms->data(), syms->size());
|
||||
delete syms;
|
||||
}
|
||||
|
||||
symbols program::find_symbols_by_name(const char* name) {
|
||||
drgn_symbol** syms;
|
||||
size_t count;
|
||||
|
||||
if (error err(
|
||||
drgn_program_find_symbols_by_name(ptr.get(), nullptr, &syms, &count));
|
||||
err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
return std::unique_ptr<std::span<drgn_symbol*>, SymbolsDeleter>(
|
||||
new std::span(syms, count));
|
||||
}
|
||||
|
||||
const char* symbol::name(drgn_symbol* sym) {
|
||||
return drgn_symbol_name(sym);
|
||||
}
|
||||
|
||||
} // namespace drgnplusplus
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <exception>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <sstream>
|
||||
#include <variant>
|
||||
|
||||
@ -26,9 +27,10 @@ extern "C" {
|
||||
// Declare drgn structs and only refer to them by pointers to avoid exposing
|
||||
// drgn.h.
|
||||
struct drgn_error;
|
||||
struct drgn_program;
|
||||
struct drgn_func_iterator;
|
||||
struct drgn_program;
|
||||
struct drgn_qualified_type;
|
||||
struct drgn_symbol;
|
||||
}
|
||||
|
||||
namespace drgnplusplus {
|
||||
@ -50,6 +52,11 @@ class error : public std::exception {
|
||||
std::unique_ptr<drgn_error, Deleter> ptr;
|
||||
};
|
||||
|
||||
struct SymbolsDeleter {
|
||||
void operator()(std::span<drgn_symbol*>*) noexcept;
|
||||
};
|
||||
using symbols = std::unique_ptr<std::span<drgn_symbol*>, SymbolsDeleter>;
|
||||
|
||||
class program {
|
||||
public:
|
||||
struct Deleter {
|
||||
@ -59,6 +66,8 @@ class program {
|
||||
program();
|
||||
program(drgn_program* prog) : ptr(prog){};
|
||||
|
||||
symbols find_symbols_by_name(const char* name);
|
||||
|
||||
drgn_program* get() {
|
||||
return ptr.get();
|
||||
}
|
||||
@ -111,4 +120,8 @@ class func_iterator {
|
||||
pointer current = nullptr;
|
||||
};
|
||||
|
||||
namespace symbol {
|
||||
const char* name(drgn_symbol*);
|
||||
}
|
||||
|
||||
} // namespace drgnplusplus
|
||||
|
@ -18,7 +18,9 @@
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
|
||||
#include "DrgnUtils.h"
|
||||
@ -26,32 +28,77 @@
|
||||
|
||||
namespace ObjectIntrospection {
|
||||
|
||||
std::unordered_map<std::string, std::string>
|
||||
OIGenerator::oilStrongToWeakSymbolsMap(drgnplusplus::program& prog) {
|
||||
static constexpr std::string_view strongSymbolPrefix =
|
||||
"int ObjectIntrospection::getObjectSize<";
|
||||
static constexpr std::string_view weakSymbolPrefix =
|
||||
"int ObjectIntrospection::getObjectSizeImpl<";
|
||||
|
||||
std::unordered_map<std::string, std::pair<std::string, std::string>>
|
||||
templateArgsToSymbolsMap;
|
||||
|
||||
auto symbols = prog.find_symbols_by_name(nullptr);
|
||||
for (drgn_symbol* sym : *symbols) {
|
||||
auto symName = drgnplusplus::symbol::name(sym);
|
||||
auto demangled = boost::core::demangle(symName);
|
||||
|
||||
if (demangled.starts_with(strongSymbolPrefix)) {
|
||||
auto& matchedSyms = templateArgsToSymbolsMap[demangled.substr(
|
||||
strongSymbolPrefix.length())];
|
||||
if (!matchedSyms.first.empty()) {
|
||||
LOG(WARNING) << "non-unique symbols found: `" << matchedSyms.first
|
||||
<< "` and `" << symName << "`";
|
||||
}
|
||||
matchedSyms.first = symName;
|
||||
} else if (demangled.starts_with(weakSymbolPrefix)) {
|
||||
auto& matchedSyms =
|
||||
templateArgsToSymbolsMap[demangled.substr(weakSymbolPrefix.length())];
|
||||
if (!matchedSyms.second.empty()) {
|
||||
LOG(WARNING) << "non-unique symbols found: `" << matchedSyms.first
|
||||
<< "` and `" << symName << "`";
|
||||
}
|
||||
matchedSyms.second = symName;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> strongToWeakSymbols;
|
||||
for (auto& [_, val] : templateArgsToSymbolsMap) {
|
||||
if (val.first.empty() || val.second.empty()) {
|
||||
continue;
|
||||
}
|
||||
strongToWeakSymbols[std::move(val.first)] = std::move(val.second);
|
||||
}
|
||||
|
||||
return strongToWeakSymbols;
|
||||
}
|
||||
|
||||
std::vector<std::tuple<drgn_qualified_type, std::string>>
|
||||
OIGenerator::findOilTypesAndNames(drgnplusplus::program& prog) {
|
||||
auto strongToWeakSymbols = oilStrongToWeakSymbolsMap(prog);
|
||||
|
||||
std::vector<std::tuple<drgn_qualified_type, std::string>> out;
|
||||
|
||||
// TODO: Clean up this loop when switching to
|
||||
// drgn_program_find_function_by_address.
|
||||
for (auto& func : drgnplusplus::func_iterator(prog)) {
|
||||
std::string fqdn;
|
||||
std::string strongLinkageName;
|
||||
{
|
||||
char* fqdnChars;
|
||||
size_t fqdnLen;
|
||||
if (drgnplusplus::error err(
|
||||
drgn_type_fully_qualified_name(func.type, &fqdnChars, &fqdnLen));
|
||||
err) {
|
||||
LOG(ERROR) << "error getting drgn type fully qualified name: " << err;
|
||||
throw err;
|
||||
char* linkageNameCstr;
|
||||
if (auto err = drgnplusplus::error(
|
||||
drgn_type_linkage_name(func.type, &linkageNameCstr))) {
|
||||
// throw err;
|
||||
continue;
|
||||
}
|
||||
fqdn = std::string(fqdnChars, fqdnLen);
|
||||
strongLinkageName = linkageNameCstr;
|
||||
}
|
||||
|
||||
if (!fqdn.starts_with("ObjectIntrospection::getObjectSize<")) {
|
||||
continue;
|
||||
}
|
||||
if (drgn_type_num_parameters(func.type) != 2) {
|
||||
continue;
|
||||
}
|
||||
if (drgn_type_num_template_parameters(func.type) != 1) {
|
||||
continue;
|
||||
std::string weakLinkageName;
|
||||
if (auto search = strongToWeakSymbols.find(strongLinkageName);
|
||||
search != strongToWeakSymbols.end()) {
|
||||
weakLinkageName = search->second;
|
||||
} else {
|
||||
continue; // not an oil strong symbol
|
||||
}
|
||||
|
||||
auto templateParameters = drgn_type_template_parameters(func.type);
|
||||
@ -65,19 +112,7 @@ OIGenerator::findOilTypesAndNames(drgnplusplus::program& prog) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "found OIL type: " << drgn_type_name(paramType.type);
|
||||
|
||||
std::string linkageName;
|
||||
{
|
||||
char* linkageNameCstr;
|
||||
if (auto err = drgnplusplus::error(
|
||||
drgn_type_linkage_name(func.type, &linkageNameCstr))) {
|
||||
throw err;
|
||||
}
|
||||
linkageName = linkageNameCstr;
|
||||
}
|
||||
|
||||
LOG(INFO) << "found linkage name: " << linkageName;
|
||||
out.push_back({paramType, linkageName});
|
||||
out.push_back({paramType, std::move(weakLinkageName)});
|
||||
}
|
||||
|
||||
return out;
|
||||
|
@ -45,8 +45,12 @@ class OIGenerator {
|
||||
fs::path configFilePath;
|
||||
fs::path sourceFileDumpPath;
|
||||
|
||||
std::unordered_map<std::string, std::string> oilStrongToWeakSymbolsMap(
|
||||
drgnplusplus::program& prog);
|
||||
|
||||
std::vector<std::tuple<drgn_qualified_type, std::string>>
|
||||
findOilTypesAndNames(drgnplusplus::program& prog);
|
||||
|
||||
bool generateForType(const OICodeGen::Config& generatorConfig,
|
||||
const OICompiler::Config& compilerConfig,
|
||||
const drgn_qualified_type& type,
|
||||
|
Loading…
Reference in New Issue
Block a user