//===-- GsymContext.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===/ #include "llvm/DebugInfo/GSYM/GsymContext.h" #include "llvm/DebugInfo/GSYM/GsymReader.h" #include "llvm/Support/Path.h" using namespace llvm; using namespace llvm::gsym; GsymContext::GsymContext(std::unique_ptr Reader) : DIContext(CK_GSYM), Reader(std::move(Reader)) {} void GsymContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {} static bool fillLineInfoFromLocation(const SourceLocation &Location, DILineInfoSpecifier Specifier, DILineInfo &LineInfo) { // FIXME Demangle in case of DINameKind::ShortName if (Specifier.FNKind != DINameKind::None) { LineInfo.FunctionName = Location.Name.str(); } switch (Specifier.FLIKind) { case DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath: // We have no information to determine the relative path, so we fall back to // returning the absolute path. case DILineInfoSpecifier::FileLineInfoKind::RawValue: case DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath: if (Location.Dir.empty()) { if (Location.Base.empty()) LineInfo.FileName = DILineInfo::BadString; else LineInfo.FileName = Location.Base.str(); } else { SmallString<128> Path(Location.Dir); sys::path::append(Path, Location.Base); LineInfo.FileName = static_cast(Path); } break; case DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly: LineInfo.FileName = Location.Base.str(); break; default: return false; } LineInfo.Line = Location.Line; // We don't have information in GSYM to fill any of the Source, Column, // StartFileName or StartLine attributes. return true; } std::optional GsymContext::getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier) { if (Address.SectionIndex != object::SectionedAddress::UndefSection) return {}; auto ResultOrErr = Reader->lookup(Address.Address); if (!ResultOrErr) { consumeError(ResultOrErr.takeError()); return {}; } const auto &Result = *ResultOrErr; DILineInfo LineInfo; if (Result.Locations.empty()) { // No debug info for this, we just had a symbol from the symbol table. // FIXME Demangle in case of DINameKind::ShortName if (Specifier.FNKind != DINameKind::None) LineInfo.FunctionName = Result.FuncName.str(); } else if (!fillLineInfoFromLocation(Result.Locations.front(), Specifier, LineInfo)) return {}; LineInfo.StartAddress = Result.FuncRange.start(); return LineInfo; } std::optional GsymContext::getLineInfoForDataAddress(object::SectionedAddress Address) { // We can't implement this, there's no such information in the GSYM file. return {}; } DILineInfoTable GsymContext::getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier) { if (Size == 0) return DILineInfoTable(); if (Address.SectionIndex != llvm::object::SectionedAddress::UndefSection) return DILineInfoTable(); if (auto FuncInfoOrErr = Reader->getFunctionInfo(Address.Address)) { DILineInfoTable Table; if (FuncInfoOrErr->OptLineTable) { const gsym::LineTable < = *FuncInfoOrErr->OptLineTable; const uint64_t StartAddr = Address.Address; const uint64_t EndAddr = Address.Address + Size; for (const auto &LineEntry : LT) { if (StartAddr <= LineEntry.Addr && LineEntry.Addr < EndAddr) { // Use LineEntry.Addr, LineEntry.File (which is a file index into the // files tables from the GsymReader), and LineEntry.Line (source line // number) to add stuff to the DILineInfoTable } } } return Table; } else { consumeError(FuncInfoOrErr.takeError()); return DILineInfoTable(); } } DIInliningInfo GsymContext::getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier) { auto ResultOrErr = Reader->lookup(Address.Address); if (!ResultOrErr) return {}; const auto &Result = *ResultOrErr; DIInliningInfo InlineInfo; for (const auto &Location : Result.Locations) { DILineInfo LineInfo; if (!fillLineInfoFromLocation(Location, Specifier, LineInfo)) return {}; // Hm, that's probably something that should only be filled in the first or // last frame? LineInfo.StartAddress = Result.FuncRange.start(); InlineInfo.addFrame(LineInfo); } return InlineInfo; } std::vector GsymContext::getLocalsForAddress(object::SectionedAddress Address) { // We can't implement this, there's no such information in the GSYM file. return {}; }