]> git.proxmox.com Git - mirror_frr.git/blame - tools/frr-llvm-debuginfo.cpp
Merge pull request #10916 from rampxxxx/feat_frr_ubi8_docker
[mirror_frr.git] / tools / frr-llvm-debuginfo.cpp
CommitLineData
d71449a3
DL
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
44struct dbginfo {
45 llvm::DebugInfoFinder finder;
46 std::map<std::string, llvm::DICompositeType *> tab;
47};
48
49struct 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
71bool 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}