brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 62b4caa Raw
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 &LT = *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