Skip to content

Commit

Permalink
oil: switch to using an impl function with no default implementation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeHillion authored Feb 2, 2023
1 parent 6f786b4 commit 8956ca5
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 42 deletions.
30 changes: 19 additions & 11 deletions include/ObjectIntrospection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -141,25 +141,25 @@ 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);
responseCode != Response::OIL_SUCCESS) {
return responseCode;
}

return lib->getObjectSize((void *)&ObjectAddr, ObjectSize);
return lib->getObjectSize((void *)&objectAddr, objectSize);
}

private:
Expand Down Expand Up @@ -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

/*
Expand All @@ -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
}

Expand Down
23 changes: 23 additions & 0 deletions src/DrgnUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 14 additions & 1 deletion src/DrgnUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@
#include <exception>
#include <iterator>
#include <memory>
#include <span>
#include <sstream>
#include <variant>

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 {
Expand All @@ -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 {
Expand All @@ -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();
}
Expand Down Expand Up @@ -111,4 +120,8 @@ class func_iterator {
pointer current = nullptr;
};

namespace symbol {
const char* name(drgn_symbol*);
}

} // namespace drgnplusplus
95 changes: 65 additions & 30 deletions src/OIGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,87 @@

#include <glog/logging.h>

#include <boost/core/demangle.hpp>
#include <fstream>
#include <unordered_map>
#include <variant>

#include "DrgnUtils.h"
#include "OIUtils.h"

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);
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/OIGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 8956ca5

Please sign in to comment.