Ejemplo n.º 1
0
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)) {
    // The address may correspond to instruction in some inlined function,
    // so we have to build the chain of inlined functions and take the
    // name of the topmost function in it.
    const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
        CU->getInlinedChainForAddress(Address);
    if (InlinedChain.size() > 0) {
      const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain[0];
      if (const char *Name = TopFunctionDIE.getSubroutineName(CU))
        FunctionName = Name;
    }
  }
  if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
    const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
    const bool NeedsAbsoluteFilePath =
        Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
    getFileLineInfoForCompileUnit(CU, LineTable, Address,
                                  NeedsAbsoluteFilePath,
                                  FileName, Line, Column);
  }
  return DILineInfo(StringRef(FileName), StringRef(FunctionName),
                    Line, Column);
}
Ejemplo n.º 2
0
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address,
    DILineInfoSpecifier specifier) {
  // First, get the offset of the compile unit.
  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;
    }
  }
  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 DILineInfo(fileName, functionName, line, column);
}
Ejemplo n.º 3
0
DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
    uint64_t Size,
    DILineInfoSpecifier Specifier) {
  DILineInfoTable  Lines;
  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
  if (!CU)
    return Lines;

  std::string FunctionName = "<invalid>";
  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
    // The address may correspond to instruction in some inlined function,
    // so we have to build the chain of inlined functions and take the
    // name of the topmost function in it.
    const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
        CU->getInlinedChainForAddress(Address);
    if (InlinedChain.size() > 0) {
      const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain[0];
      if (const char *Name = TopFunctionDIE.getSubroutineName(CU))
        FunctionName = Name;
    }
  }

  StringRef  FuncNameRef = StringRef(FunctionName);

  // If the Specifier says we don't need FileLineInfo, just
  // return the top-most function at the starting address.
  if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
    Lines.push_back(std::make_pair(Address, 
                                   DILineInfo(StringRef("<invalid>"), 
                                              FuncNameRef, 0, 0)));
    return Lines;
  }

  const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
  const bool NeedsAbsoluteFilePath =
      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);

  // Get the index of row we're looking for in the line table.
  std::vector<uint32_t> RowVector;
  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
    return Lines;

  uint32_t NumRows = RowVector.size();
  for (uint32_t i = 0; i < NumRows; ++i) {
    uint32_t RowIndex = RowVector[i];
    // Take file number and line/column from the row.
    const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
    std::string FileName = "<invalid>";
    getFileNameForCompileUnit(CU, LineTable, Row.File,
                              NeedsAbsoluteFilePath, FileName);
    Lines.push_back(std::make_pair(Row.Address, 
                                   DILineInfo(StringRef(FileName),
                                         FuncNameRef, Row.Line, Row.Column)));
  }

  return Lines;
}
Ejemplo n.º 4
0
DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
    DILineInfoSpecifier Specifier) {
  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
  if (!CU)
    return DIInliningInfo();

  const DWARFDebugInfoEntryInlinedChain &InlinedChain =
      CU->getInlinedChainForAddress(Address);
  if (InlinedChain.DIEs.size() == 0)
    return DIInliningInfo();

  DIInliningInfo InliningInfo;
  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
  const DWARFLineTable *LineTable = 0;
  for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
    const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
    std::string FileName = "<invalid>";
    std::string FunctionName = "<invalid>";
    uint32_t Line = 0;
    uint32_t Column = 0;
    // Get function name if necessary.
    if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
      if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
        FunctionName = Name;
    }
    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
      const bool NeedsAbsoluteFilePath =
          Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
      if (i == 0) {
        // For the topmost frame, initialize the line table of this
        // compile unit and fetch file/line info from it.
        LineTable = getLineTableForCompileUnit(CU);
        // For the topmost routine, get file/line info from line table.
        getFileLineInfoForCompileUnit(CU, LineTable, Address,
                                      NeedsAbsoluteFilePath,
                                      FileName, Line, Column);
      } else {
        // Otherwise, use call file, call line and call column from
        // previous DIE in inlined chain.
        getFileNameForCompileUnit(CU, LineTable, CallFile,
                                  NeedsAbsoluteFilePath, FileName);
        Line = CallLine;
        Column = CallColumn;
      }
      // Get call file/line/column of a current DIE.
      if (i + 1 < n) {
        FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
                                   CallColumn);
      }
    }
    DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
                     Line, Column);
    InliningInfo.addFrame(Frame);
  }
  return InliningInfo;
}
Ejemplo n.º 5
0
DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
    uint64_t Size,
    DILineInfoSpecifier Specifier) {
  DILineInfoTable  Lines;
  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
  if (!CU)
    return Lines;

  std::string FunctionName = "<invalid>";
  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
    getFunctionNameForAddress(CU, Address, FunctionName);
  }

  // If the Specifier says we don't need FileLineInfo, just
  // return the top-most function at the starting address.
  if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
    DILineInfo Result;
    Result.FunctionName = FunctionName;
    Lines.push_back(std::make_pair(Address, Result));
    return Lines;
  }

  const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
  const bool NeedsAbsoluteFilePath =
      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);

  // Get the index of row we're looking for in the line table.
  std::vector<uint32_t> RowVector;
  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
    return Lines;

  for (uint32_t RowIndex : RowVector) {
    // Take file number and line/column from the row.
    const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
    DILineInfo Result;
    getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
                              Result.FileName);
    Result.FunctionName = FunctionName;
    Result.Line = Row.Line;
    Result.Column = Row.Column;
    Lines.push_back(std::make_pair(Row.Address, Result));
  }

  return Lines;
}
Ejemplo n.º 6
0
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
    DILineInfoSpecifier Specifier) {
  DILineInfo Result;

  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
  if (!CU)
    return Result;
  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
    getFunctionNameForAddress(CU, Address, Result.FunctionName);
  }
  if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
    const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
    const bool NeedsAbsoluteFilePath =
        Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
    getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
                                  Result);
  }
  return Result;
}
Ejemplo n.º 7
0
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address,
    DILineInfoSpecifier specifier) {
  // First, get the offset of the compile unit.
  uint32_t cuOffset = getDebugAranges()->findAddress(address);
  // Retrieve the compile unit.
  DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset);
  if (!cu)
    return DILineInfo();
  const char *fileName = "<invalid>";
  const char *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)
      functionName = function_die->getSubprogramName(cu);
  }
  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.
      uint64_t hiPC = cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(
          cu, DW_AT_high_pc, -1ULL);
      uint32_t rowIndex = lineTable->lookupAddress(address, hiPC);
      if (rowIndex != -1U) {
        const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex];
        // Take file/line info from the line table.
        fileName = lineTable->Prologue.FileNames[row.File - 1].Name.c_str();
        line = row.Line;
        column = row.Column;
      }
    }
  }
  return DILineInfo(fileName, functionName, line, column);
}
Ejemplo n.º 8
0
DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
    DILineInfoSpecifier Specifier) {
  DIInliningInfo InliningInfo;

  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
  if (!CU)
    return InliningInfo;

  const DWARFLineTable *LineTable = nullptr;
  const bool NeedsAbsoluteFilePath =
      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
  const DWARFDebugInfoEntryInlinedChain &InlinedChain =
      CU->getInlinedChainForAddress(Address);
  if (InlinedChain.DIEs.size() == 0) {
    // If there is no DIE for address (e.g. it is in unavailable .dwo file),
    // try to at least get file/line info from symbol table.
    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
      DILineInfo Frame;
      LineTable = getLineTableForCompileUnit(CU);
      if (getFileLineInfoForCompileUnit(CU, LineTable, Address,
                                        NeedsAbsoluteFilePath, Frame)) {
        InliningInfo.addFrame(Frame);
      }
    }
    return InliningInfo;
  }

  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
  for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
    const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
    DILineInfo Frame;
    // Get function name if necessary.
    if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
      if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
        Frame.FunctionName = Name;
    }
    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
      if (i == 0) {
        // For the topmost frame, initialize the line table of this
        // compile unit and fetch file/line info from it.
        LineTable = getLineTableForCompileUnit(CU);
        // For the topmost routine, get file/line info from line table.
        getFileLineInfoForCompileUnit(CU, LineTable, Address,
                                      NeedsAbsoluteFilePath, Frame);
      } else {
        // Otherwise, use call file, call line and call column from
        // previous DIE in inlined chain.
        getFileNameForCompileUnit(CU, LineTable, CallFile,
                                  NeedsAbsoluteFilePath, Frame.FileName);
        Frame.Line = CallLine;
        Frame.Column = CallColumn;
      }
      // Get call file/line/column of a current DIE.
      if (i + 1 < n) {
        FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
                                   CallColumn);
      }
    }
    InliningInfo.addFrame(Frame);
  }
  return InliningInfo;
}