]>
git.proxmox.com Git - mirror_frr.git/blob - tools/frr-llvm-debuginfo.cpp
1 // SPDX-License-Identifier: Unlicense
3 #include <llvm-c/BitReader.h>
4 #include <llvm-c/BitWriter.h>
5 #include <llvm-c/Core.h>
6 #include <llvm-c/DebugInfo.h>
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>
17 #include "frr-llvm-debuginfo.h"
19 /* llvm::DebugInfoFinder is unfortunately not exposed in the llvm-c API... */
22 llvm::DebugInfoFinder finder
;
23 std::map
<std::string
, llvm::DICompositeType
*> tab
;
26 struct dbginfo
*dbginfo_load(LLVMModuleRef _mod
)
28 llvm::Module
*mod
= llvm::unwrap(_mod
);
29 struct dbginfo
*info
= new dbginfo();
31 info
->finder
.processModule(*mod
);
33 for (auto ty
: info
->finder
.types()) {
34 if (ty
->getMetadataID() != llvm::Metadata::DICompositeTypeKind
)
37 llvm::DICompositeType
*cty
= (llvm::DICompositeType
*)ty
;
38 /* empty forward declarations aka "struct foobar;" */
39 if (cty
->getElements().size() == 0)
42 info
->tab
.emplace(std::move(ty
->getName().str()), cty
);
48 bool dbginfo_struct_member(struct dbginfo
*info
, LLVMTypeRef _typ
,
49 unsigned long long idx
, char **struct_name
,
55 llvm::Type
*typ
= llvm::unwrap(_typ
);
57 if (!typ
->isStructTy())
60 llvm::StructType
*styp
= (llvm::StructType
*)typ
;
61 auto sname
= styp
->getStructName();
63 if (!sname
.startswith("struct."))
65 sname
= sname
.drop_front(7);
67 size_t dot
= sname
.find_last_of(".");
68 if (dot
!= sname
.npos
)
69 sname
= sname
.take_front(dot
);
71 auto item
= info
->tab
.find(sname
.str());
72 if (item
== info
->tab
.end())
75 auto elements
= item
->second
->getElements();
76 if (idx
>= elements
.size())
79 auto elem
= elements
[idx
];
81 if (elem
->getMetadataID() != llvm::Metadata::DIDerivedTypeKind
)
84 llvm::DIDerivedType
*dtyp
= (llvm::DIDerivedType
*)elem
;
86 *struct_name
= strdup(sname
.str().c_str());
87 *member_name
= strdup(dtyp
->getName().str().c_str());