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