コード例 #1
0
ファイル: llvm-rtdyld.cpp プロジェクト: ADonut/LLVM-GPGPU
static int printLineInfoForInput() {
  // Load any dylibs requested on the command line.
  loadDylibs();

  // If we don't have any input files, read from stdin.
  if (!InputFileList.size())
    InputFileList.push_back("-");
  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
    // Instantiate a dynamic linker.
    TrivialMemoryManager MemMgr;
    RuntimeDyld Dyld(&MemMgr);

    // Load the input memory buffer.
    std::unique_ptr<MemoryBuffer> InputBuffer;
    std::unique_ptr<ObjectImage> LoadedObject;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
                                                     InputBuffer))
      return Error("unable to read input: '" + ec.message() + "'");

    // Load the object file
    LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.release())));
    if (!LoadedObject) {
      return Error(Dyld.getErrorString());
    }

    // Resolve all the relocations we can.
    Dyld.resolveRelocations();

    std::unique_ptr<DIContext> Context(
        DIContext::getDWARFContext(LoadedObject->getObjectFile()));

    // Use symbol info to iterate functions in the object.
    for (object::symbol_iterator I = LoadedObject->begin_symbols(),
                                 E = LoadedObject->end_symbols();
         I != E; ++I) {
      object::SymbolRef::Type SymType;
      if (I->getType(SymType)) continue;
      if (SymType == object::SymbolRef::ST_Function) {
        StringRef  Name;
        uint64_t   Addr;
        uint64_t   Size;
        if (I->getName(Name)) continue;
        if (I->getAddress(Addr)) continue;
        if (I->getSize(Size)) continue;

        outs() << "Function: " << Name << ", Size = " << Size << "\n";

        DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
        DILineInfoTable::iterator  Begin = Lines.begin();
        DILineInfoTable::iterator  End = Lines.end();
        for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
          outs() << "  Line info @ " << It->first - Addr << ": "
                 << It->second.FileName << ", line:" << It->second.Line << "\n";
        }
      }
    }
  }

  return 0;
}
コード例 #2
0
ファイル: DWARFContext.cpp プロジェクト: Hoernchen/llvm
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;
}
コード例 #3
0
ファイル: LLVMExtra.cpp プロジェクト: 465060874/robovm
void LLVMGetLineInfoForAddressRange(LLVMObjectFileRef O, uint64_t Address, uint64_t Size, int* OutSize, uint64_t** Out) {
  DIContext* ctx = DIContext::getDWARFContext(*(unwrap(O)->getBinary()));
  DILineInfoTable lineTable = ctx->getLineInfoForAddressRange(Address, Size);
  *OutSize = lineTable.size();
  *Out = NULL;
  if (lineTable.size() > 0) {
    *Out = (uint64_t*) calloc(lineTable.size() * 2, sizeof(uint64_t));
    for (int i = 0; i < lineTable.size(); i++) {
      std::pair<uint64_t, DILineInfo> p = lineTable[i];
      (*Out)[i * 2] = p.first;
      (*Out)[i * 2 + 1] = p.second.Line;
    }
  }
}
コード例 #4
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;
}
コード例 #5
0
ファイル: PDBContext.cpp プロジェクト: 8l/SPIRV-LLVM
DILineInfoTable
PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
                                       DILineInfoSpecifier Specifier) {
  if (Size == 0)
    return DILineInfoTable();

  DILineInfoTable Table;
  auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
  if (!LineNumbers || LineNumbers->getChildCount() == 0)
    return Table;

  while (auto LineInfo = LineNumbers->getNext()) {
    DILineInfo LineEntry =
        getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
    Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
  }
  return Table;
}
コード例 #6
0
ファイル: LLILCJit.cpp プロジェクト: manu-silicon/llilc
void ObjectLoadListener::getDebugInfoForObject(
    const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) {
  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();

  // TODO: This extracts DWARF information from the object file, but we will
  // want to also be able to eventually extract WinCodeView information as well
  DWARFContextInMemory DwarfContext(DebugObj);

  // Use symbol info to find the function size.
  // If there are funclets, they will each have separate symbols, so we need
  // to sum the sizes, since the EE wants a single report for the entire
  // function+funclets.

  uint64_t Addr = UINT64_MAX;
  uint64_t Size = 0;

  std::vector<std::pair<SymbolRef, uint64_t>> SymbolSizes =
      object::computeSymbolSizes(DebugObj);

  for (const auto &Pair : SymbolSizes) {
    object::SymbolRef Symbol = Pair.first;
    SymbolRef::Type SymType = Symbol.getType();
    if (SymType != SymbolRef::ST_Function)
      continue;

    // Function info
    ErrorOr<uint64_t> AddrOrError = Symbol.getAddress();
    if (!AddrOrError) {
      continue; // Error.
    }
    uint64_t SingleAddr = AddrOrError.get();
    uint64_t SingleSize = Pair.second;
    if (SingleAddr < Addr) {
      // The main function is always laid out first
      Addr = SingleAddr;
    }
    Size += SingleSize;
  }

  uint32_t LastDebugOffset = (uint32_t)-1;
  uint32_t NumDebugRanges = 0;
  ICorDebugInfo::OffsetMapping *OM;

  DILineInfoTable Lines = DwarfContext.getLineInfoForAddressRange(Addr, Size);

  DILineInfoTable::iterator Begin = Lines.begin();
  DILineInfoTable::iterator End = Lines.end();

  // Count offset entries. Will skip an entry if the current IL offset
  // matches the previous offset.
  for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
    uint32_t LineNumber = (It->second).Line;

    if (LineNumber != LastDebugOffset) {
      NumDebugRanges++;
      LastDebugOffset = LineNumber;
    }
  }

  // Reset offset
  LastDebugOffset = (uint32_t)-1;

  if (NumDebugRanges > 0) {
    // Allocate OffsetMapping array
    unsigned SizeOfArray =
        (NumDebugRanges) * sizeof(ICorDebugInfo::OffsetMapping);
    OM = (ICorDebugInfo::OffsetMapping *)Context->JitInfo->allocateArray(
        SizeOfArray);

    unsigned CurrentDebugEntry = 0;

    // Iterate through the debug entries and save IL offset, native
    // offset, and source reason
    for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
      int Offset = It->first;
      uint32_t LineNumber = (It->second).Line;

      // We store info about if the instruction is being recorded because
      // it is a call in the column field
      bool IsCall = (It->second).Column == 1;

      if (LineNumber != LastDebugOffset) {
        LastDebugOffset = LineNumber;
        OM[CurrentDebugEntry].nativeOffset = Offset;
        OM[CurrentDebugEntry].ilOffset = LineNumber;
        OM[CurrentDebugEntry].source = IsCall ? ICorDebugInfo::CALL_INSTRUCTION
                                              : ICorDebugInfo::STACK_EMPTY;
        CurrentDebugEntry++;
      }
    }

    // Send array of OffsetMappings to CLR EE
    CORINFO_METHOD_INFO *MethodInfo = Context->MethodInfo;
    CORINFO_METHOD_HANDLE MethodHandle = MethodInfo->ftn;

    Context->JitInfo->setBoundaries(MethodHandle, NumDebugRanges, OM);

    getDebugInfoForLocals(DwarfContext, Addr, Size);
  }
}
コード例 #7
0
ファイル: llvm-rtdyld.cpp プロジェクト: cephdon/llvm
static int printLineInfoForInput() {
  // Load any dylibs requested on the command line.
  loadDylibs();

  // If we don't have any input files, read from stdin.
  if (!InputFileList.size())
    InputFileList.push_back("-");
  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
    // Instantiate a dynamic linker.
    TrivialMemoryManager MemMgr;
    RuntimeDyld Dyld(MemMgr, MemMgr);

    // Load the input memory buffer.

    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
        MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
    if (std::error_code EC = InputBuffer.getError())
      return Error("unable to read input: '" + EC.message() + "'");

    ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));

    if (std::error_code EC = MaybeObj.getError())
      return Error("unable to create object file: '" + EC.message() + "'");

    ObjectFile &Obj = **MaybeObj;

    // Load the object file
    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo =
      Dyld.loadObject(Obj);

    if (Dyld.hasError())
      return Error(Dyld.getErrorString());

    // Resolve all the relocations we can.
    Dyld.resolveRelocations();

    OwningBinary<ObjectFile> DebugObj = LoadedObjInfo->getObjectForDebug(Obj);

    std::unique_ptr<DIContext> Context(
      new DWARFContextInMemory(*DebugObj.getBinary()));

    // Use symbol info to iterate functions in the object.
    for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(),
                                 E = DebugObj.getBinary()->symbol_end();
         I != E; ++I) {
      object::SymbolRef::Type SymType;
      if (I->getType(SymType)) continue;
      if (SymType == object::SymbolRef::ST_Function) {
        StringRef  Name;
        uint64_t   Addr;
        uint64_t   Size;
        if (I->getName(Name)) continue;
        if (I->getAddress(Addr)) continue;
        if (I->getSize(Size)) continue;

        outs() << "Function: " << Name << ", Size = " << Size << "\n";

        DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
        DILineInfoTable::iterator  Begin = Lines.begin();
        DILineInfoTable::iterator  End = Lines.end();
        for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
          outs() << "  Line info @ " << It->first - Addr << ": "
                 << It->second.FileName << ", line:" << It->second.Line << "\n";
        }
      }
    }
  }

  return 0;
}
コード例 #8
0
ファイル: llvm-rtdyld.cpp プロジェクト: IanLee1521/ares
static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
  assert(LoadObjects || !UseDebugObj);

  // Load any dylibs requested on the command line.
  loadDylibs();

  // If we don't have any input files, read from stdin.
  if (!InputFileList.size())
    InputFileList.push_back("-");
  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
    // Instantiate a dynamic linker.
    TrivialMemoryManager MemMgr;
    RuntimeDyld Dyld(MemMgr, MemMgr);

    // Load the input memory buffer.

    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
        MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
    if (std::error_code EC = InputBuffer.getError())
      return Error("unable to read input: '" + EC.message() + "'");

    ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));

    if (std::error_code EC = MaybeObj.getError())
      return Error("unable to create object file: '" + EC.message() + "'");

    ObjectFile &Obj = **MaybeObj;

    OwningBinary<ObjectFile> DebugObj;
    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr;
    ObjectFile *SymbolObj = &Obj;
    if (LoadObjects) {
      // Load the object file
      LoadedObjInfo =
        Dyld.loadObject(Obj);

      if (Dyld.hasError())
        return Error(Dyld.getErrorString());

      // Resolve all the relocations we can.
      Dyld.resolveRelocations();

      if (UseDebugObj) {
        DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
        SymbolObj = DebugObj.getBinary();
        LoadedObjInfo.reset();
      }
    }

    std::unique_ptr<DIContext> Context(
      new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get()));

    std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
        object::computeSymbolSizes(*SymbolObj);

    // Use symbol info to iterate functions in the object.
    for (const auto &P : SymAddr) {
      object::SymbolRef Sym = P.first;
      if (Sym.getType() == object::SymbolRef::ST_Function) {
        ErrorOr<StringRef> Name = Sym.getName();
        if (!Name)
          continue;
        ErrorOr<uint64_t> AddrOrErr = Sym.getAddress();
        if (!AddrOrErr)
          continue;
        uint64_t Addr = *AddrOrErr;

        uint64_t Size = P.second;
        // If we're not using the debug object, compute the address of the
        // symbol in memory (rather than that in the unrelocated object file)
        // and use that to query the DWARFContext.
        if (!UseDebugObj && LoadObjects) {
          object::section_iterator Sec(SymbolObj->section_end());
          Sym.getSection(Sec);
          StringRef SecName;
          Sec->getName(SecName);
          uint64_t SectionLoadAddress =
            LoadedObjInfo->getSectionLoadAddress(*Sec);
          if (SectionLoadAddress != 0)
            Addr += SectionLoadAddress - Sec->getAddress();
        }

        outs() << "Function: " << *Name << ", Size = " << Size
               << ", Addr = " << Addr << "\n";

        DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
        DILineInfoTable::iterator  Begin = Lines.begin();
        DILineInfoTable::iterator  End = Lines.end();
        for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
          outs() << "  Line info @ " << It->first - Addr << ": "
                 << It->second.FileName << ", line:" << It->second.Line << "\n";
        }
      }
    }
  }

  return 0;
}