blob: 16ad18bed73f2edb5d5de1b34946cb49b5cdbdbf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  | 
// SPDX-License-Identifier: Unlicense
#include <llvm-c/BitReader.h>
#include <llvm-c/BitWriter.h>
#include <llvm-c/Core.h>
#include <llvm-c/DebugInfo.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/DebugInfo.h>
#include <llvm/IR/DebugInfoMetadata.h>
#include <llvm/Support/raw_ostream.h>
#include <map>
#include "frr-llvm-debuginfo.h"
/* llvm::DebugInfoFinder is unfortunately not exposed in the llvm-c API... */
struct dbginfo {
	llvm::DebugInfoFinder finder;
	std::map<std::string, llvm::DICompositeType *> tab;
};
struct dbginfo *dbginfo_load(LLVMModuleRef _mod)
{
	llvm::Module *mod = llvm::unwrap(_mod);
	struct dbginfo *info = new dbginfo();
	info->finder.processModule(*mod);
	for (auto ty : info->finder.types()) {
		if (ty->getMetadataID() != llvm::Metadata::DICompositeTypeKind)
			continue;
		llvm::DICompositeType *cty = (llvm::DICompositeType *)ty;
		/* empty forward declarations aka "struct foobar;" */
		if (cty->getElements().size() == 0)
			continue;
		info->tab.emplace(std::move(ty->getName().str()), cty);
	}
	return info;
}
bool dbginfo_struct_member(struct dbginfo *info, LLVMTypeRef _typ,
			   unsigned long long idx, char **struct_name,
			   char **member_name)
{
	*struct_name = NULL;
	*member_name = NULL;
	llvm::Type *typ = llvm::unwrap(_typ);
	if (!typ->isStructTy())
		return false;
	llvm::StructType *styp = (llvm::StructType *)typ;
	auto sname = styp->getStructName();
	if (!sname.startswith("struct."))
		return false;
	sname = sname.drop_front(7);
	size_t dot = sname.find_last_of(".");
	if (dot != sname.npos)
		sname = sname.take_front(dot);
	auto item = info->tab.find(sname.str());
	if (item == info->tab.end())
		return false;
	auto elements = item->second->getElements();
	if (idx >= elements.size())
		return false;
	auto elem = elements[idx];
	if (elem->getMetadataID() != llvm::Metadata::DIDerivedTypeKind)
		return false;
	llvm::DIDerivedType *dtyp = (llvm::DIDerivedType *)elem;
	*struct_name = strdup(sname.str().c_str());
	*member_name = strdup(dtyp->getName().str().c_str());
	return true;
}
  |