diff options
Diffstat (limited to 'llvm/lib/DebugInfo')
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFContext.cpp | 132 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFContext.h | 23 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFDebugLine.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFDebugLine.h | 8 | 
4 files changed, 127 insertions, 63 deletions
diff --git a/llvm/lib/DebugInfo/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARFContext.cpp index 388688bd480..3f9edd305b9 100644 --- a/llvm/lib/DebugInfo/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARFContext.cpp @@ -145,75 +145,93 @@ namespace {    };  } -DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t offset) { +DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {    if (CUs.empty())      parseCompileUnits(); -  DWARFCompileUnit *i = std::lower_bound(CUs.begin(), CUs.end(), offset, -                                         OffsetComparator()); -  if (i != CUs.end()) -    return &*i; +  DWARFCompileUnit *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset, +                                          OffsetComparator()); +  if (CU != CUs.end()) +    return &*CU;    return 0;  } -DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address, -    DILineInfoSpecifier specifier) { +DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {    // First, get the offset of the compile unit. -  uint32_t cuOffset = getDebugAranges()->findAddress(address); +  uint32_t CUOffset = getDebugAranges()->findAddress(Address);    // Retrieve the compile unit. -  DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset); -  if (!cu) -    return DILineInfo(); -  SmallString<16> fileName("<invalid>"); -  SmallString<16> functionName("<invalid>"); -  uint32_t line = 0; -  uint32_t column = 0; -  if (specifier.needs(DILineInfoSpecifier::FunctionName)) { -    const DWARFDebugInfoEntryMinimal *function_die = -        cu->getFunctionDIEForAddress(address); -    if (function_die) { -      if (const char *name = function_die->getSubprogramName(cu)) -        functionName = name; +  return getCompileUnitForOffset(CUOffset); +} + +static bool getFileNameForCompileUnit( +    DWARFCompileUnit *CU, const DWARFDebugLine::LineTable *LineTable, +    uint64_t FileIndex, bool NeedsAbsoluteFilePath, std::string &FileName) { +  if (CU == 0 || +      LineTable == 0 || +      !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath, +                                     FileName)) +    return false; +  if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) { +    // We may still need to append compilation directory of compile unit. +    SmallString<16> AbsolutePath; +    if (const char *CompilationDir = CU->getCompilationDir()) { +      sys::path::append(AbsolutePath, CompilationDir);      } +    sys::path::append(AbsolutePath, FileName); +    FileName = AbsolutePath.str();    } -  if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) { -    // Get the line table for this compile unit. -    const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu); -    if (lineTable) { -      // Get the index of the row we're looking for in the line table. -      uint32_t rowIndex = lineTable->lookupAddress(address); -      if (rowIndex != -1U) { -        const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex]; -        // Take file/line info from the line table. -        const DWARFDebugLine::FileNameEntry &fileNameEntry = -            lineTable->Prologue.FileNames[row.File - 1]; -        fileName = fileNameEntry.Name; -        if (specifier.needs(DILineInfoSpecifier::AbsoluteFilePath) && -            sys::path::is_relative(fileName.str())) { -          // Append include directory of file (if it is present in line table) -          // and compilation directory of compile unit to make path absolute. -          const char *includeDir = 0; -          if (uint64_t includeDirIndex = fileNameEntry.DirIdx) { -            includeDir = lineTable->Prologue -                         .IncludeDirectories[includeDirIndex - 1]; -          } -          SmallString<16> absFileName; -          if (includeDir == 0 || sys::path::is_relative(includeDir)) { -            if (const char *compilationDir = cu->getCompilationDir()) -              sys::path::append(absFileName, compilationDir); -          } -          if (includeDir) { -            sys::path::append(absFileName, includeDir); -          } -          sys::path::append(absFileName, fileName.str()); -          fileName = absFileName; -        } -        line = row.Line; -        column = row.Column; -      } +  return true; +} + +bool +DWARFContext::getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, +                                            uint64_t Address, +                                            bool NeedsAbsoluteFilePath, +                                            std::string &FileName, +                                            uint32_t &Line, uint32_t &Column) { +  // Get the line table for this compile unit. +  const DWARFDebugLine::LineTable *LineTable = getLineTableForCompileUnit(CU); +  if (!LineTable) +    return false; +  // Get the index of row we're looking for in the line table. +  uint32_t RowIndex = LineTable->lookupAddress(Address); +  if (RowIndex == -1U) +    return false; +  // Take file number and line/column from the row. +  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; +  if (!getFileNameForCompileUnit(CU, LineTable, Row.File, +                                 NeedsAbsoluteFilePath, FileName)) +    return false; +  Line = Row.Line; +  Column = Row.Column; +  return true; +} + +DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, +    DILineInfoSpecifier Specifier) { +  DWARFCompileUnit *CU = getCompileUnitForAddress(Address); +  if (!CU) +    return DILineInfo(); +  std::string FileName = "<invalid>"; +  std::string FunctionName = "<invalid>"; +  uint32_t Line = 0; +  uint32_t Column = 0; +  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { +    const DWARFDebugInfoEntryMinimal *FunctionDIE = +        CU->getFunctionDIEForAddress(Address); +    if (FunctionDIE) { +      if (const char *Name = FunctionDIE->getSubprogramName(CU)) +        FunctionName = Name;      }    } -  return DILineInfo(fileName, functionName, line, column); +  if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { +    const bool NeedsAbsoluteFilePath = +        Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); +    getFileLineInfoForCompileUnit(CU, Address, NeedsAbsoluteFilePath, +                                  FileName, Line, Column); +  } +  return DILineInfo(StringRef(FileName), StringRef(FunctionName), +                    Line, Column);  }  void DWARFContextInMemory::anchor() { } diff --git a/llvm/lib/DebugInfo/DWARFContext.h b/llvm/lib/DebugInfo/DWARFContext.h index 870b541a900..ff343de716a 100644 --- a/llvm/lib/DebugInfo/DWARFContext.h +++ b/llvm/lib/DebugInfo/DWARFContext.h @@ -54,9 +54,6 @@ public:      return &CUs[index];    } -  /// Return the compile unit that includes an offset (relative to .debug_info). -  DWARFCompileUnit *getCompileUnitForOffset(uint32_t offset); -    /// Get a pointer to the parsed DebugAbbrev object.    const DWARFDebugAbbrev *getDebugAbbrev(); @@ -67,8 +64,8 @@ public:    const DWARFDebugLine::LineTable *    getLineTableForCompileUnit(DWARFCompileUnit *cu); -  virtual DILineInfo getLineInfoForAddress(uint64_t address, -      DILineInfoSpecifier specifier = DILineInfoSpecifier()); +  virtual DILineInfo getLineInfoForAddress(uint64_t Address, +      DILineInfoSpecifier Specifier = DILineInfoSpecifier());    bool isLittleEndian() const { return IsLittleEndian; } @@ -82,9 +79,23 @@ public:    static bool isSupportedVersion(unsigned version) {      return version == 2 || version == 3;    } +private: +  /// Return the compile unit that includes an offset (relative to .debug_info). +  DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); + +  /// Return the compile unit which contains instruction with provided +  /// address. +  DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); + +  /// Fetches filename, line and column number for given address and +  /// compile unit. Returns true on success. +  bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, +                                     uint64_t Address, +                                     bool NeedsAbsoluteFilePath, +                                     std::string &FileName, +                                     uint32_t &Line, uint32_t &Column);  }; -  /// DWARFContextInMemory is the simplest possible implementation of a  /// DWARFContext. It assumes all content is available in memory and stores  /// pointers to it. diff --git a/llvm/lib/DebugInfo/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARFDebugLine.cpp index d99575d8003..267364adfac 100644 --- a/llvm/lib/DebugInfo/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARFDebugLine.cpp @@ -10,6 +10,7 @@  #include "DWARFDebugLine.h"  #include "llvm/Support/Dwarf.h"  #include "llvm/Support/Format.h" +#include "llvm/Support/Path.h"  #include "llvm/Support/raw_ostream.h"  #include <algorithm>  using namespace llvm; @@ -513,3 +514,29 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {    }    return index;  } + +bool +DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, +                                              bool NeedsAbsoluteFilePath, +                                              std::string &Result) const { +  if (FileIndex == 0 || FileIndex > Prologue.FileNames.size()) +    return false; +  const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; +  const char *FileName = Entry.Name; +  if (!NeedsAbsoluteFilePath || +      sys::path::is_absolute(FileName)) { +    Result = FileName; +    return true; +  } +  SmallString<16> FilePath; +  uint64_t IncludeDirIndex = Entry.DirIdx; +  // Be defensive about the contents of Entry. +  if (IncludeDirIndex > 0 && +      IncludeDirIndex <= Prologue.IncludeDirectories.size()) { +    const char *IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; +    sys::path::append(FilePath, IncludeDir); +  } +  sys::path::append(FilePath, FileName); +  Result = FilePath.str(); +  return true; +} diff --git a/llvm/lib/DebugInfo/DWARFDebugLine.h b/llvm/lib/DebugInfo/DWARFDebugLine.h index 6382b45a93a..586dd7e8784 100644 --- a/llvm/lib/DebugInfo/DWARFDebugLine.h +++ b/llvm/lib/DebugInfo/DWARFDebugLine.h @@ -12,6 +12,7 @@  #include "llvm/Support/DataExtractor.h"  #include <map> +#include <string>  #include <vector>  namespace llvm { @@ -174,6 +175,13 @@ public:      // Returns the index of the row with file/line info for a given address,      // or -1 if there is no such row.      uint32_t lookupAddress(uint64_t address) const; + +    // Extracts filename by its index in filename table in prologue. +    // Returns true on success. +    bool getFileNameByIndex(uint64_t FileIndex, +                            bool NeedsAbsoluteFilePath, +                            std::string &Result) const; +      void dump(raw_ostream &OS) const;      struct Prologue Prologue;  | 

