xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/GSYM/GsymContext.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- GsymContext.cpp ------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===/
8 
9 #include "llvm/DebugInfo/GSYM/GsymContext.h"
10 
11 #include "llvm/DebugInfo/GSYM/GsymReader.h"
12 #include "llvm/Support/Path.h"
13 
14 using namespace llvm;
15 using namespace llvm::gsym;
16 
GsymContext(std::unique_ptr<GsymReader> Reader)17 GsymContext::GsymContext(std::unique_ptr<GsymReader> Reader)
18     : DIContext(CK_GSYM), Reader(std::move(Reader)) {}
19 
dump(raw_ostream & OS,DIDumpOptions DumpOpts)20 void GsymContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {}
21 
fillLineInfoFromLocation(const SourceLocation & Location,DILineInfoSpecifier Specifier,DILineInfo & LineInfo)22 static bool fillLineInfoFromLocation(const SourceLocation &Location,
23                                      DILineInfoSpecifier Specifier,
24                                      DILineInfo &LineInfo) {
25   // FIXME Demangle in case of DINameKind::ShortName
26   if (Specifier.FNKind != DINameKind::None) {
27     LineInfo.FunctionName = Location.Name.str();
28   }
29 
30   switch (Specifier.FLIKind) {
31   case DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath:
32     // We have no information to determine the relative path, so we fall back to
33     // returning the absolute path.
34   case DILineInfoSpecifier::FileLineInfoKind::RawValue:
35   case DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath:
36     if (Location.Dir.empty()) {
37       if (Location.Base.empty())
38         LineInfo.FileName = DILineInfo::BadString;
39       else
40         LineInfo.FileName = Location.Base.str();
41     } else {
42       SmallString<128> Path(Location.Dir);
43       sys::path::append(Path, Location.Base);
44       LineInfo.FileName = static_cast<std::string>(Path);
45     }
46     break;
47 
48   case DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly:
49     LineInfo.FileName = Location.Base.str();
50     break;
51 
52   default:
53     return false;
54   }
55   LineInfo.Line = Location.Line;
56 
57   // We don't have information in GSYM to fill any of the Source, Column,
58   // StartFileName or StartLine attributes.
59 
60   return true;
61 }
62 
63 std::optional<DILineInfo>
getLineInfoForAddress(object::SectionedAddress Address,DILineInfoSpecifier Specifier)64 GsymContext::getLineInfoForAddress(object::SectionedAddress Address,
65                                    DILineInfoSpecifier Specifier) {
66   if (Address.SectionIndex != object::SectionedAddress::UndefSection)
67     return {};
68 
69   auto ResultOrErr = Reader->lookup(Address.Address);
70 
71   if (!ResultOrErr) {
72     consumeError(ResultOrErr.takeError());
73     return {};
74   }
75 
76   const auto &Result = *ResultOrErr;
77 
78   DILineInfo LineInfo;
79 
80   if (Result.Locations.empty()) {
81     // No debug info for this, we just had a symbol from the symbol table.
82 
83     // FIXME Demangle in case of DINameKind::ShortName
84     if (Specifier.FNKind != DINameKind::None)
85       LineInfo.FunctionName = Result.FuncName.str();
86   } else if (!fillLineInfoFromLocation(Result.Locations.front(), Specifier,
87                                        LineInfo))
88     return {};
89 
90   LineInfo.StartAddress = Result.FuncRange.start();
91 
92   return LineInfo;
93 }
94 
95 std::optional<DILineInfo>
getLineInfoForDataAddress(object::SectionedAddress Address)96 GsymContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
97   // We can't implement this, there's no such information in the GSYM file.
98 
99   return {};
100 }
101 
102 DILineInfoTable
getLineInfoForAddressRange(object::SectionedAddress Address,uint64_t Size,DILineInfoSpecifier Specifier)103 GsymContext::getLineInfoForAddressRange(object::SectionedAddress Address,
104                                         uint64_t Size,
105                                         DILineInfoSpecifier Specifier) {
106   if (Size == 0)
107     return DILineInfoTable();
108 
109   if (Address.SectionIndex != llvm::object::SectionedAddress::UndefSection)
110     return DILineInfoTable();
111 
112   if (auto FuncInfoOrErr = Reader->getFunctionInfo(Address.Address)) {
113     DILineInfoTable Table;
114     if (FuncInfoOrErr->OptLineTable) {
115       const gsym::LineTable &LT = *FuncInfoOrErr->OptLineTable;
116       const uint64_t StartAddr = Address.Address;
117       const uint64_t EndAddr = Address.Address + Size;
118       for (const auto &LineEntry : LT) {
119         if (StartAddr <= LineEntry.Addr && LineEntry.Addr < EndAddr) {
120           // Use LineEntry.Addr, LineEntry.File (which is a file index into the
121           // files tables from the GsymReader), and LineEntry.Line (source line
122           // number) to add stuff to the DILineInfoTable
123         }
124       }
125     }
126     return Table;
127   } else {
128     consumeError(FuncInfoOrErr.takeError());
129     return DILineInfoTable();
130   }
131 }
132 
133 DIInliningInfo
getInliningInfoForAddress(object::SectionedAddress Address,DILineInfoSpecifier Specifier)134 GsymContext::getInliningInfoForAddress(object::SectionedAddress Address,
135                                        DILineInfoSpecifier Specifier) {
136   auto ResultOrErr = Reader->lookup(Address.Address);
137 
138   if (!ResultOrErr)
139     return {};
140 
141   const auto &Result = *ResultOrErr;
142 
143   DIInliningInfo InlineInfo;
144 
145   for (const auto &Location : Result.Locations) {
146     DILineInfo LineInfo;
147 
148     if (!fillLineInfoFromLocation(Location, Specifier, LineInfo))
149       return {};
150 
151     // Hm, that's probably something that should only be filled in the first or
152     // last frame?
153     LineInfo.StartAddress = Result.FuncRange.start();
154 
155     InlineInfo.addFrame(LineInfo);
156   }
157 
158   return InlineInfo;
159 }
160 
161 std::vector<DILocal>
getLocalsForAddress(object::SectionedAddress Address)162 GsymContext::getLocalsForAddress(object::SectionedAddress Address) {
163   // We can't implement this, there's no such information in the GSYM file.
164 
165   return {};
166 }
167