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