]>
git.proxmox.com Git - mirror_frr.git/blob - tools/frr-llvm-debuginfo.cpp
1 // This is free and unencumbered software released into the public domain.
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
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.
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.
24 // For more information, please refer to <http://unlicense.org/>
26 #include <llvm-c/BitReader.h>
27 #include <llvm-c/BitWriter.h>
28 #include <llvm-c/Core.h>
29 #include <llvm-c/DebugInfo.h>
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>
40 #include "frr-llvm-debuginfo.h"
42 /* llvm::DebugInfoFinder is unfortunately not exposed in the llvm-c API... */
45 llvm::DebugInfoFinder finder
;
46 std::map
<std::string
, llvm::DICompositeType
*> tab
;
49 struct dbginfo
*dbginfo_load(LLVMModuleRef _mod
)
51 llvm::Module
*mod
= llvm::unwrap(_mod
);
52 struct dbginfo
*info
= new dbginfo();
54 info
->finder
.processModule(*mod
);
56 for (auto ty
: info
->finder
.types()) {
57 if (ty
->getMetadataID() != llvm::Metadata::DICompositeTypeKind
)
60 llvm::DICompositeType
*cty
= (llvm::DICompositeType
*)ty
;
61 /* empty forward declarations aka "struct foobar;" */
62 if (cty
->getElements().size() == 0)
65 info
->tab
.emplace(std::move(ty
->getName().str()), cty
);
71 bool dbginfo_struct_member(struct dbginfo
*info
, LLVMTypeRef _typ
,
72 unsigned long long idx
, char **struct_name
,
78 llvm::Type
*typ
= llvm::unwrap(_typ
);
80 if (!typ
->isStructTy())
83 llvm::StructType
*styp
= (llvm::StructType
*)typ
;
84 auto sname
= styp
->getStructName();
86 if (!sname
.startswith("struct."))
88 sname
= sname
.drop_front(7);
90 size_t dot
= sname
.find_last_of(".");
91 if (dot
!= sname
.npos
)
92 sname
= sname
.take_front(dot
);
94 auto item
= info
->tab
.find(sname
.str());
95 if (item
== info
->tab
.end())
98 auto elements
= item
->second
->getElements();
99 if (idx
>= elements
.size())
102 auto elem
= elements
[idx
];
104 if (elem
->getMetadataID() != llvm::Metadata::DIDerivedTypeKind
)
107 llvm::DIDerivedType
*dtyp
= (llvm::DIDerivedType
*)elem
;
109 *struct_name
= strdup(sname
.str().c_str());
110 *member_name
= strdup(dtyp
->getName().str().c_str());