]> git.proxmox.com Git - mirror_frr.git/blob - tools/frr-llvm-debuginfo.cpp
Merge pull request #8759 from idryzhov/ospf6-vrf-fix
[mirror_frr.git] / tools / frr-llvm-debuginfo.cpp
1 // This is free and unencumbered software released into the public domain.
2 //
3 // Anyone is free to copy, modify, publish, use, compile, sell, or
4 // distribute this software, either in source code form or as a compiled
5 // binary, for any purpose, commercial or non-commercial, and by any
6 // means.
7 //
8 // In jurisdictions that recognize copyright laws, the author or authors
9 // of this software dedicate any and all copyright interest in the
10 // software to the public domain. We make this dedication for the benefit
11 // of the public at large and to the detriment of our heirs and
12 // successors. We intend this dedication to be an overt act of
13 // relinquishment in perpetuity of all present and future rights to this
14 // software under copyright law.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 // OTHER DEALINGS IN THE SOFTWARE.
23 //
24 // For more information, please refer to <http://unlicense.org/>
25
26 #include <llvm-c/BitReader.h>
27 #include <llvm-c/BitWriter.h>
28 #include <llvm-c/Core.h>
29 #include <llvm-c/DebugInfo.h>
30
31 #include <llvm/IR/Module.h>
32 #include <llvm/IR/Value.h>
33 #include <llvm/IR/Type.h>
34 #include <llvm/IR/DebugInfo.h>
35 #include <llvm/IR/DebugInfoMetadata.h>
36 #include <llvm/Support/raw_ostream.h>
37
38 #include <map>
39
40 #include "frr-llvm-debuginfo.h"
41
42 /* llvm::DebugInfoFinder is unfortunately not exposed in the llvm-c API... */
43
44 struct dbginfo {
45 llvm::DebugInfoFinder finder;
46 std::map<std::string, llvm::DICompositeType *> tab;
47 };
48
49 struct dbginfo *dbginfo_load(LLVMModuleRef _mod)
50 {
51 llvm::Module *mod = llvm::unwrap(_mod);
52 struct dbginfo *info = new dbginfo();
53
54 info->finder.processModule(*mod);
55
56 for (auto ty : info->finder.types()) {
57 if (ty->getMetadataID() != llvm::Metadata::DICompositeTypeKind)
58 continue;
59
60 llvm::DICompositeType *cty = (llvm::DICompositeType *)ty;
61 /* empty forward declarations aka "struct foobar;" */
62 if (cty->getElements().size() == 0)
63 continue;
64
65 info->tab.emplace(std::move(ty->getName().str()), cty);
66 }
67
68 return info;
69 }
70
71 bool dbginfo_struct_member(struct dbginfo *info, LLVMTypeRef _typ,
72 unsigned long long idx, char **struct_name,
73 char **member_name)
74 {
75 *struct_name = NULL;
76 *member_name = NULL;
77
78 llvm::Type *typ = llvm::unwrap(_typ);
79
80 if (!typ->isStructTy())
81 return false;
82
83 llvm::StructType *styp = (llvm::StructType *)typ;
84 auto sname = styp->getStructName();
85
86 if (!sname.startswith("struct."))
87 return false;
88 sname = sname.drop_front(7);
89
90 size_t dot = sname.find_last_of(".");
91 if (dot != sname.npos)
92 sname = sname.take_front(dot);
93
94 auto item = info->tab.find(sname.str());
95 if (item == info->tab.end())
96 return false;
97
98 auto elements = item->second->getElements();
99 if (idx >= elements.size())
100 return false;
101
102 auto elem = elements[idx];
103
104 if (elem->getMetadataID() != llvm::Metadata::DIDerivedTypeKind)
105 return false;
106
107 llvm::DIDerivedType *dtyp = (llvm::DIDerivedType *)elem;
108
109 *struct_name = strdup(sname.str().c_str());
110 *member_name = strdup(dtyp->getName().str().c_str());
111 return true;
112 }