[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 &LT = *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