blob: eedb1e638fd1aa03a42f3209fba30e67e1bc155a [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===- FunctionInfo.h -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
11#define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
12
13#include "llvm/DebugInfo/GSYM/InlineInfo.h"
14#include "llvm/DebugInfo/GSYM/LineEntry.h"
15#include "llvm/DebugInfo/GSYM/Range.h"
16#include "llvm/DebugInfo/GSYM/StringTable.h"
17#include <tuple>
18#include <vector>
19
20namespace llvm {
21class raw_ostream;
22namespace gsym {
23
24/// Function information in GSYM files encodes information for one
25/// contiguous address range. The name of the function is encoded as
26/// a string table offset and allows multiple functions with the same
27/// name to share the name string in the string table. Line tables are
28/// stored in a sorted vector of gsym::LineEntry objects and are split
29/// into line tables for each function. If a function has a discontiguous
30/// range, it will be split into two gsym::FunctionInfo objects. If the
31/// function has inline functions, the information will be encoded in
32/// the "Inline" member, see gsym::InlineInfo for more information.
33struct FunctionInfo {
34 AddressRange Range;
35 uint32_t Name; ///< String table offset in the string table.
36 std::vector<gsym::LineEntry> Lines;
37 InlineInfo Inline;
38
39 FunctionInfo(uint64_t Addr = 0, uint64_t Size = 0, uint32_t N = 0)
40 : Range(Addr, Addr + Size), Name(N) {}
41
42 bool hasRichInfo() const {
43 /// Returns whether we have something else than range and name. When
44 /// converting information from a symbol table and from debug info, we
45 /// might end up with multiple FunctionInfo objects for the same range
46 /// and we need to be able to tell which one is the better object to use.
47 return !Lines.empty() || Inline.isValid();
48 }
49
50 bool isValid() const {
51 /// Address and size can be zero and there can be no line entries for a
52 /// symbol so the only indication this entry is valid is if the name is
53 /// not zero. This can happen when extracting information from symbol
54 /// tables that do not encode symbol sizes. In that case only the
55 /// address and name will be filled in.
56 return Name != 0;
57 }
58
59 uint64_t startAddress() const { return Range.Start; }
60 uint64_t endAddress() const { return Range.End; }
61 uint64_t size() const { return Range.size(); }
62 void setStartAddress(uint64_t Addr) { Range.Start = Addr; }
63 void setEndAddress(uint64_t Addr) { Range.End = Addr; }
64 void setSize(uint64_t Size) { Range.End = Range.Start + Size; }
65
66 void clear() {
67 Range = {0, 0};
68 Name = 0;
69 Lines.clear();
70 Inline.clear();
71 }
72};
73
74inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
75 return LHS.Range == RHS.Range && LHS.Name == RHS.Name &&
76 LHS.Lines == RHS.Lines && LHS.Inline == RHS.Inline;
77}
78inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
79 return !(LHS == RHS);
80}
81/// This sorting will order things consistently by address range first, but then
82/// followed by inlining being valid and line tables. We might end up with a
83/// FunctionInfo from debug info that will have the same range as one from the
84/// symbol table, but we want to quickly be able to sort and use the best version
85/// when creating the final GSYM file.
86inline bool operator<(const FunctionInfo &LHS, const FunctionInfo &RHS) {
87 // First sort by address range
88 if (LHS.Range != RHS.Range)
89 return LHS.Range < RHS.Range;
90
91 // Then sort by inline
92 if (LHS.Inline.isValid() != RHS.Inline.isValid())
93 return RHS.Inline.isValid();
94
95 // If the number of lines is the same, then compare line table entries
96 if (LHS.Lines.size() == RHS.Lines.size())
97 return LHS.Lines < RHS.Lines;
98 // Then sort by number of line table entries (more is better)
99 return LHS.Lines.size() < RHS.Lines.size();
100}
101
102raw_ostream &operator<<(raw_ostream &OS, const FunctionInfo &R);
103
104} // namespace gsym
105} // namespace llvm
106
107#endif // #ifndef LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H