[llvm] LLVM symbolizer gsym support (PR #134847)
Mariusz Kwiczala via llvm-commits
llvm-commits at lists.llvm.org
Wed May 7 01:32:33 PDT 2025
================
@@ -0,0 +1,169 @@
+//===-- GsymDIContext.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/GsymDIContext.h"
+
+#include "llvm/DebugInfo/GSYM/GsymReader.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+using namespace llvm::gsym;
+
+GsymDIContext::GsymDIContext(std::unique_ptr<GsymReader> Reader)
+ : DIContext(CK_GSYM), Reader(std::move(Reader)) {}
+
+void GsymDIContext::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<std::string>(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<DILineInfo>
+GsymDIContext::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<DILineInfo>
+GsymDIContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ // We can't implement this, there's no such information in the GSYM file.
+
+ return {};
+}
+
+DILineInfoTable
+GsymDIContext::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
+GsymDIContext::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<DILocal>
+GsymDIContext::getLocalsForAddress(object::SectionedAddress Address) {
+ // We can't implement this, there's no such information in the GSYM file.
+
+ return std::vector<DILocal>();
----------------
sfc-gh-mkwiczala wrote:
Thank you. Changed
https://github.com/llvm/llvm-project/pull/134847
More information about the llvm-commits
mailing list