Пример #1
0
void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
                                        const MachineFunction *MF) {
  // Skip this instruction if it has the same location as the previous one.
  if (DL == CurFn->LastLoc)
    return;

  const DIScope *Scope = DL.get()->getScope();
  if (!Scope)
    return;

  // Skip this line if it is longer than the maximum we can record.
  LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true);
  if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() ||
      LI.isNeverStepInto())
    return;

  ColumnInfo CI(DL.getCol(), /*EndColumn=*/0);
  if (CI.getStartColumn() != DL.getCol())
    return;

  if (!CurFn->HaveLineInfo)
    CurFn->HaveLineInfo = true;
  unsigned FileId = 0;
  if (CurFn->LastLoc.get() && CurFn->LastLoc->getFile() == DL->getFile())
    FileId = CurFn->LastFileId;
  else
    FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
  CurFn->LastLoc = DL;

  unsigned FuncId = CurFn->FuncId;
  if (const DILocation *SiteLoc = DL->getInlinedAt()) {
    const DILocation *Loc = DL.get();

    // If this location was actually inlined from somewhere else, give it the ID
    // of the inline call site.
    FuncId =
        getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;

    // Ensure we have links in the tree of inline call sites.
    bool FirstLoc = true;
    while ((SiteLoc = Loc->getInlinedAt())) {
      InlineSite &Site =
          getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
      if (!FirstLoc)
        addLocIfNotPresent(Site.ChildSites, Loc);
      FirstLoc = false;
      Loc = SiteLoc;
    }
    addLocIfNotPresent(CurFn->ChildSites, Loc);
  }

  OS.EmitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(),
                        /*PrologueEnd=*/false,
                        /*IsStmt=*/false, DL->getFilename());
}
Пример #2
0
void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
                                        const MachineFunction *MF) {
  // Skip this instruction if it has the same location as the previous one.
  if (DL == CurFn->LastLoc)
    return;

  const DIScope *Scope = DL.get()->getScope();
  if (!Scope)
    return;

  // Skip this line if it is longer than the maximum we can record.
  LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true);
  if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() ||
      LI.isNeverStepInto())
    return;

  ColumnInfo CI(DL.getCol(), /*EndColumn=*/0);
  if (CI.getStartColumn() != DL.getCol())
    return;

  if (!CurFn->HaveLineInfo)
    CurFn->HaveLineInfo = true;
  unsigned FileId = 0;
  if (CurFn->LastLoc.get() && CurFn->LastLoc->getFile() == DL->getFile())
    FileId = CurFn->LastFileId;
  else
    FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
  CurFn->LastLoc = DL;

  unsigned FuncId = CurFn->FuncId;
  if (const DILocation *Loc = DL->getInlinedAt()) {
    // If this location was actually inlined from somewhere else, give it the ID
    // of the inline call site.
    FuncId = getInlineSite(DL.get()).SiteFuncId;
    // Ensure we have links in the tree of inline call sites.
    const DILocation *ChildLoc = nullptr;
    while (Loc->getInlinedAt()) {
      InlineSite &Site = getInlineSite(Loc);
      if (ChildLoc) {
        // Record the child inline site if not already present.
        auto B = Site.ChildSites.begin(), E = Site.ChildSites.end();
        if (std::find(B, E, Loc) != E)
          break;
        Site.ChildSites.push_back(Loc);
      }
      ChildLoc = Loc;
    }
  }

  Asm->OutStreamer->EmitCVLocDirective(FuncId, FileId, DL.getLine(),
                                       DL.getCol(), /*PrologueEnd=*/false,
                                       /*IsStmt=*/false, DL->getFilename());
}
Пример #3
0
/// updateInlinedAtInfo - Helper function used by fixupLineNumbers to
/// recursively update InlinedAtEntry of a DebugLoc.
static DebugLoc updateInlinedAtInfo(const DebugLoc &DL, 
                                    const DebugLoc &InlinedAtDL,
                                    LLVMContext &Ctx) {
  if (MDNode *IA = DL.getInlinedAt(Ctx)) {
    DebugLoc NewInlinedAtDL 
      = updateInlinedAtInfo(DebugLoc::getFromDILocation(IA), InlinedAtDL, Ctx);
    return DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(Ctx),
                         NewInlinedAtDL.getAsMDNode(Ctx));
  }

  return DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(Ctx),
                       InlinedAtDL.getAsMDNode(Ctx));
}
Пример #4
0
static void print_source_line(raw_ostream &stream, DebugLoc Loc)
{
    MDNode *inlinedAt = Loc.getInlinedAt(jl_LLVMContext);
    if (inlinedAt != NULL) {
        DebugLoc inlineloc = DebugLoc::getFromDILocation(inlinedAt);
        stream << "Source line: " << inlineloc.getLine() << "\n";

        DILexicalBlockFile innerscope = DILexicalBlockFile(Loc.getScope(jl_LLVMContext));
        stream << "Source line: [inline] " << innerscope.getFilename().str().c_str() << ':' << Loc.getLine() << "\n";
    }
    else {
        stream << "Source line: " << Loc.getLine() << "\n";
    }
}
Пример #5
0
void DataChecks::CreateCrossCheck(IRBuilder<> &Builder, Value *V) {
  IntegerType *PtrIntTy = Builder.getIntPtrTy(*DL);

  // Cast the value to IntPtrType
  auto *VTy = V->getType();
  if (VTy->isPointerTy())
    V = Builder.CreatePtrToInt(V, PtrIntTy);
  else
    V = Builder.CreateZExtOrTrunc(V, PtrIntTy);

  // Call the check function.
  // TODO: Optimize by inlining the call?
  if (XCheckLog) {
    DebugLoc Loc = Builder.GetInsertPoint()->getDebugLoc();
    Value *caller = Builder.CreateGlobalStringPtr(Builder.GetInsertBlock()->getParent()->getName());
    Value *line, *col, *file;
    if (Loc) {
      line = Builder.getInt32(Loc.getLine());
      col = Builder.getInt32(Loc.getCol());
      file = Builder.CreateGlobalStringPtr(Loc->getFilename());
    } else {
      line = Builder.getInt32(-1);
      col = Builder.getInt32(-1);
      file = Builder.CreateGlobalStringPtr("unknown");
    }
    Builder.CreateCall(CheckFnTy, CheckFn, { caller, file, line, col, V });
  } else {
    Builder.CreateCall(CheckFnTy, CheckFn, {V});
  }

  NumCrossChecks++;
}
Пример #6
0
/// \brief Get the weight for an instruction.
///
/// The "weight" of an instruction \p Inst is the number of samples
/// collected on that instruction at runtime. To retrieve it, we
/// need to compute the line number of \p Inst relative to the start of its
/// function. We use HeaderLineno to compute the offset. We then
/// look up the samples collected for \p Inst using BodySamples.
///
/// \param Inst Instruction to query.
///
/// \returns the weight of \p Inst.
ErrorOr<uint64_t>
SampleProfileLoader::getInstWeight(const Instruction &Inst) const {
  DebugLoc DLoc = Inst.getDebugLoc();
  if (!DLoc)
    return std::error_code();

  const FunctionSamples *FS = findFunctionSamples(Inst);
  if (!FS)
    return std::error_code();

  const DILocation *DIL = DLoc;
  unsigned Lineno = DLoc.getLine();
  unsigned HeaderLineno = DIL->getScope()->getSubprogram()->getLine();

  uint32_t LineOffset = getOffset(Lineno, HeaderLineno);
  uint32_t Discriminator = DIL->getDiscriminator();
  ErrorOr<uint64_t> R = FS->findSamplesAt(LineOffset, Discriminator);
  if (R) {
    bool FirstMark =
        CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator);
    if (FirstMark) {
      const Function *F = Inst.getParent()->getParent();
      LLVMContext &Ctx = F->getContext();
      emitOptimizationRemark(Ctx, DEBUG_TYPE, *F, DLoc,
                             Twine("Applied ") + Twine(*R) +
                                 " samples from profile");
    }
    DEBUG(dbgs() << "    " << Lineno << "." << DIL->getDiscriminator() << ":"
                 << Inst << " (line offset: " << Lineno - HeaderLineno << "."
                 << DIL->getDiscriminator() << " - weight: " << R.get()
                 << ")\n");
  }
  return R;
}
Пример #7
0
DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
  if (!DL)
    return;
  Filename = DL->getFilename();
  Line = DL->getLine();
  Column = DL->getColumn();
}
Пример #8
0
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
    : Key(Key), Loc(Loc) {
  if (Loc) {
    Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
           Twine(Loc.getCol())).str();
  } else {
    Val = "<UNKNOWN LOCATION>";
  }
}
Пример #9
0
unsigned ScopeInfoFinder::getLastLine(Function *F)
{
  if (F == NULL || F->begin() == F->end()) //empty block
    return 0;
  const BasicBlock & BB = F->back();
  const Instruction & I = BB.back();
  DebugLoc Loc = I.getDebugLoc();
  if (Loc.isUnknown()) 
    return 0;
  return Loc.getLine();
}
Пример #10
0
unsigned ScopeInfoFinder::getInstLine(const Instruction *I)
{
  DebugLoc Loc = I->getDebugLoc();
  if (Loc.isUnknown()) {
    if (DEBUG_MATCHER) {
      errs() << "Unknown LOC" << "\n";
    }
    return 0;
  }
  return Loc.getLine();
}
void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL,
                                                const MachineFunction *MF) {
  const MDNode *Scope = DL.getScope();
  if (!Scope)
    return;
  StringRef Filename = getFullFilepath(Scope);

  // Skip this instruction if it has the same file:line as the previous one.
  assert(CurFn);
  if (!CurFn->Instrs.empty()) {
    const InstrInfoTy &LastInstr = InstrInfo[CurFn->Instrs.back()];
    if (LastInstr.Filename == Filename && LastInstr.LineNumber == DL.getLine())
      return;
  }
  FileNameRegistry.add(Filename);

  MCSymbol *MCL = Asm->MMI->getContext().CreateTempSymbol();
  Asm->OutStreamer.EmitLabel(MCL);
  CurFn->Instrs.push_back(MCL);
  InstrInfo[MCL] = InstrInfoTy(Filename, DL.getLine());
}
Пример #12
0
void Matcher::processBasicBlock(Function *F)
{
  for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; FI++) {
    /** Use first and last instruction to get the scope information **/
    Instruction *first = & FI->front();
    Instruction *last = & FI->back();
    if (first == NULL || last == NULL) {
      errs() << "NULL scope instructions " << "\n";
      continue;
    }
    DebugLoc Loc = first->getDebugLoc();
    if (Loc.isUnknown()) {
      errs() << "Unknown LOC information" << "\n";
      continue;
    }
    errs() << "Block :" << Loc.getLine();
    Loc = last->getDebugLoc();
    if (Loc.isUnknown()) {
      errs() << "Unknown LOC information" << "\n";
      continue;
    }
    errs() << ", " << Loc.getLine() << "\n";
  }
}
Пример #13
0
/// \brief Get the weight for an instruction.
///
/// The "weight" of an instruction \p Inst is the number of samples
/// collected on that instruction at runtime. To retrieve it, we
/// need to compute the line number of \p Inst relative to the start of its
/// function. We use HeaderLineno to compute the offset. We then
/// look up the samples collected for \p Inst using BodySamples.
///
/// \param Inst Instruction to query.
///
/// \returns The profiled weight of I.
unsigned SampleProfileLoader::getInstWeight(Instruction &Inst) {
  DebugLoc DLoc = Inst.getDebugLoc();
  unsigned Lineno = DLoc.getLine();
  if (Lineno < HeaderLineno)
    return 0;

  DILocation DIL(DLoc.getAsMDNode(*Ctx));
  int LOffset = Lineno - HeaderLineno;
  unsigned Discriminator = DIL.getDiscriminator();
  unsigned Weight = Samples->samplesAt(LOffset, Discriminator);
  DEBUG(dbgs() << "    " << Lineno << "." << Discriminator << ":" << Inst
               << " (line offset: " << LOffset << "." << Discriminator
               << " - weight: " << Weight << ")\n");
  return Weight;
}
Пример #14
0
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
                          const LLVMContext &Ctx) {
  if (!DL.isUnknown()) { // Print source line info.
    DIScope Scope(DL.getScope(Ctx));
    assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
    // Omit the directory, because it's likely to be long and uninteresting.
    CommentOS << Scope.getFilename();
    CommentOS << ':' << DL.getLine();
    if (DL.getCol() != 0)
      CommentOS << ':' << DL.getCol();
    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));
    if (!InlinedAtDL.isUnknown()) {
      CommentOS << " @[ ";
      printDebugLoc(InlinedAtDL, CommentOS, Ctx);
      CommentOS << " ]";
    }
  }
}
Пример #15
0
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
                          const LLVMContext &Ctx) {
  if (!DL)
    return;

  auto *Scope = cast<MDScope>(DL.getScope());
  // Omit the directory, because it's likely to be long and uninteresting.
  CommentOS << Scope->getFilename();
  CommentOS << ':' << DL.getLine();
  if (DL.getCol() != 0)
    CommentOS << ':' << DL.getCol();

  DebugLoc InlinedAtDL = DL.getInlinedAt();
  if (!InlinedAtDL)
    return;

  CommentOS << " @[ ";
  printDebugLoc(InlinedAtDL, CommentOS, Ctx);
  CommentOS << " ]";
}
Пример #16
0
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
                          const LLVMContext &Ctx) {
  if (!DL)
    return;

  DIScope Scope(DL.getScope());
  assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
  // Omit the directory, because it's likely to be long and uninteresting.
  CommentOS << Scope.getFilename();
  CommentOS << ':' << DL.getLine();
  if (DL.getCol() != 0)
    CommentOS << ':' << DL.getCol();

  DebugLoc InlinedAtDL = DL.getInlinedAt();
  if (!InlinedAtDL)
    return;

  CommentOS << " @[ ";
  printDebugLoc(InlinedAtDL, CommentOS, Ctx);
  CommentOS << " ]";
}
Пример #17
0
void getDebugLocation(const Region *R, unsigned &LineBegin, unsigned &LineEnd,
                      std::string &FileName) {
  LineBegin = -1;
  LineEnd = 0;

  for (const BasicBlock *BB : R->blocks())
    for (const Instruction &Inst : *BB) {
      DebugLoc DL = Inst.getDebugLoc();
      if (!DL)
        continue;

      auto *Scope = cast<DIScope>(DL.getScope());

      if (FileName.empty())
        FileName = Scope->getFilename();

      unsigned NewLine = DL.getLine();

      LineBegin = std::min(LineBegin, NewLine);
      LineEnd = std::max(LineEnd, NewLine);
    }
}
Пример #18
0
void DSMonitor::watch(DSNodeHandle N, std::vector<Value*> VS, std::string M) {
  if (N.isNull() || N.getNode()->isCollapsedNode()) {
    unwatch();
    return;
  }

  this->N = N;
  this->VS = VS;
  this->message = M;
  DSGraph *G = N.getNode()->getParentGraph();
  caption = getCaption(N.getNode(), G);

  if (!VS.empty()) {
    Instruction *I = getInstruction(VS[0]);
    if (I && I->getMetadata("dbg")) {
      const DebugLoc DL = I->getDebugLoc();
      auto *scope = cast<DIScope>(DL.getScope());
      location = scope->getFilename().str() + ":"
        + std::to_string(DL.getLine()) + ":"
        + std::to_string(DL.getCol());
    }
  }
}
Пример #19
0
/// \brief Get the weight for an instruction.
///
/// The "weight" of an instruction \p Inst is the number of samples
/// collected on that instruction at runtime. To retrieve it, we
/// need to compute the line number of \p Inst relative to the start of its
/// function. We use HeaderLineno to compute the offset. We then
/// look up the samples collected for \p Inst using BodySamples.
///
/// \param Inst Instruction to query.
///
/// \returns the weight of \p Inst.
ErrorOr<unsigned>
SampleProfileLoader::getInstWeight(const Instruction &Inst) const {
  DebugLoc DLoc = Inst.getDebugLoc();
  if (!DLoc)
    return std::error_code();

  unsigned Lineno = DLoc.getLine();
  if (Lineno < HeaderLineno)
    return std::error_code();

  const DILocation *DIL = DLoc;
  const FunctionSamples *FS = findFunctionSamples(Inst);
  if (!FS)
    return std::error_code();
  ErrorOr<unsigned> R =
      FS->findSamplesAt(Lineno - HeaderLineno, DIL->getDiscriminator());
  if (R)
    DEBUG(dbgs() << "    " << Lineno << "." << DIL->getDiscriminator() << ":"
                 << Inst << " (line offset: " << Lineno - HeaderLineno << "."
                 << DIL->getDiscriminator() << " - weight: " << R.get()
                 << ")\n");
  return R;
}
Пример #20
0
void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
  if (const MachineSDNode *MN = dyn_cast<MachineSDNode>(this)) {
    if (!MN->memoperands_empty()) {
      OS << "<";
      OS << "Mem:";
      for (MachineSDNode::mmo_iterator i = MN->memoperands_begin(),
           e = MN->memoperands_end(); i != e; ++i) {
        OS << **i;
        if (llvm::next(i) != e)
          OS << " ";
      }
      OS << ">";
    }
  } else if (const ShuffleVectorSDNode *SVN =
               dyn_cast<ShuffleVectorSDNode>(this)) {
    OS << "<";
    for (unsigned i = 0, e = ValueList[0].getVectorNumElements(); i != e; ++i) {
      int Idx = SVN->getMaskElt(i);
      if (i) OS << ",";
      if (Idx < 0)
        OS << "u";
      else
        OS << Idx;
    }
    OS << ">";
  } else if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) {
    OS << '<' << CSDN->getAPIntValue() << '>';
  } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) {
    if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle)
      OS << '<' << CSDN->getValueAPF().convertToFloat() << '>';
    else if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEdouble)
      OS << '<' << CSDN->getValueAPF().convertToDouble() << '>';
    else {
      OS << "<APFloat(";
      CSDN->getValueAPF().bitcastToAPInt().dump();
      OS << ")>";
    }
  } else if (const GlobalAddressSDNode *GADN =
             dyn_cast<GlobalAddressSDNode>(this)) {
    int64_t offset = GADN->getOffset();
    OS << '<';
    WriteAsOperand(OS, GADN->getGlobal());
    OS << '>';
    if (offset > 0)
      OS << " + " << offset;
    else
      OS << " " << offset;
    if (unsigned int TF = GADN->getTargetFlags())
      OS << " [TF=" << TF << ']';
  } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) {
    OS << "<" << FIDN->getIndex() << ">";
  } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(this)) {
    OS << "<" << JTDN->getIndex() << ">";
    if (unsigned int TF = JTDN->getTargetFlags())
      OS << " [TF=" << TF << ']';
  } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){
    int offset = CP->getOffset();
    if (CP->isMachineConstantPoolEntry())
      OS << "<" << *CP->getMachineCPVal() << ">";
    else
      OS << "<" << *CP->getConstVal() << ">";
    if (offset > 0)
      OS << " + " << offset;
    else
      OS << " " << offset;
    if (unsigned int TF = CP->getTargetFlags())
      OS << " [TF=" << TF << ']';
  } else if (const TargetIndexSDNode *TI = dyn_cast<TargetIndexSDNode>(this)) {
    OS << "<" << TI->getIndex() << '+' << TI->getOffset() << ">";
    if (unsigned TF = TI->getTargetFlags())
      OS << " [TF=" << TF << ']';
  } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) {
    OS << "<";
    const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
    if (LBB)
      OS << LBB->getName() << " ";
    OS << (const void*)BBDN->getBasicBlock() << ">";
  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) {
    OS << ' ' << PrintReg(R->getReg(), G ? G->getTarget().getRegisterInfo() :0);
  } else if (const ExternalSymbolSDNode *ES =
             dyn_cast<ExternalSymbolSDNode>(this)) {
    OS << "'" << ES->getSymbol() << "'";
    if (unsigned int TF = ES->getTargetFlags())
      OS << " [TF=" << TF << ']';
  } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) {
    if (M->getValue())
      OS << "<" << M->getValue() << ">";
    else
      OS << "<null>";
  } else if (const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(this)) {
    if (MD->getMD())
      OS << "<" << MD->getMD() << ">";
    else
      OS << "<null>";
  } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
    OS << ":" << N->getVT().getEVTString();
  }
  else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
    OS << "<" << *LD->getMemOperand();

    bool doExt = true;
    switch (LD->getExtensionType()) {
    default: doExt = false; break;
    case ISD::EXTLOAD:  OS << ", anyext"; break;
    case ISD::SEXTLOAD: OS << ", sext"; break;
    case ISD::ZEXTLOAD: OS << ", zext"; break;
    }
    if (doExt)
      OS << " from " << LD->getMemoryVT().getEVTString();

    const char *AM = getIndexedModeName(LD->getAddressingMode());
    if (*AM)
      OS << ", " << AM;

    OS << ">";
  } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(this)) {
    OS << "<" << *ST->getMemOperand();

    if (ST->isTruncatingStore())
      OS << ", trunc to " << ST->getMemoryVT().getEVTString();

    const char *AM = getIndexedModeName(ST->getAddressingMode());
    if (*AM)
      OS << ", " << AM;

    OS << ">";
  } else if (const MemSDNode* M = dyn_cast<MemSDNode>(this)) {
    OS << "<" << *M->getMemOperand() << ">";
  } else if (const BlockAddressSDNode *BA =
               dyn_cast<BlockAddressSDNode>(this)) {
    OS << "<";
    WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false);
    OS << ", ";
    WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false);
    OS << ">";
    if (unsigned int TF = BA->getTargetFlags())
      OS << " [TF=" << TF << ']';
  }

  if (G)
    if (unsigned Order = G->GetOrdering(this))
      OS << " [ORD=" << Order << ']';

  if (getNodeId() != -1)
    OS << " [ID=" << getNodeId() << ']';

  DebugLoc dl = getDebugLoc();
  if (G && !dl.isUnknown()) {
    DIScope
      Scope(dl.getScope(G->getMachineFunction().getFunction()->getContext()));
    OS << " dbg:";
    // Omit the directory, since it's usually long and uninteresting.
    if (Scope.Verify())
      OS << Scope.getFilename();
    else
      OS << "<unknown>";
    OS << ':' << dl.getLine();
    if (dl.getCol() != 0)
      OS << ':' << dl.getCol();
  }
}
Пример #21
0
bool SancusModuleCreator::handleFunction(Function& f)
{
    if (f.isIntrinsic() || f.isDeclaration())
        return false;

    bool modified = false;

    // HACK: clang fails to add the needed attributes to main(), add them here
    if (f.getName() == "main")
    {
        f.setSection(".init9");
        f.setAlignment(2);
        modified = true;
    }

    SancusModuleInfo info = getSancusModuleInfo(&f);
    if (info.isInSm)
    {
        f.setSection(info.getTextSection());
        modified = true;
    }
    if (info.isEntry)
        entries.push_back(&f);

    std::map<Instruction*, Instruction*> verifications;
    std::map<Instruction*, Instruction*> replacements;

    for (inst_iterator it = inst_begin(f), end = inst_end(f); it != end; ++it)
    {
        Instruction* inst = &*it;
        CallSite cs(inst);
        if (!cs)
            continue;

        Function* callee = getCalledFunction(cs);
        if (callee == nullptr)
        {
            if (CallInst* ci = cast<CallInst>(&*it))
            {
                if (ci->isInlineAsm())
                    continue;
            }

            DebugLoc loc = inst->getDebugLoc();
            std::string locStr;
            if (!loc.isUnknown())
            {
                Twine t(" (" + Twine(loc.getLine()) + ":" +
                        Twine(loc.getCol()) + ")");
                locStr = t.str();
            }

            // FIXME this warning is too strict since it also fires on "normal"
            // function pointers. we should try to warn only when a function
            // pointer is used inside an SM or is created from an SM function.
            errs() << "WARNING: In function " << f.getName() << locStr
                   << ": Function pointers not supported yet\n";
            continue;
        }
        else if (callee->isIntrinsic())
            continue;
        else if (callee->getName() == "sancus_call")
        {
            replacements[cs.getInstruction()] =
                handleSancusCall(cs).getInstruction();
            continue;
        }

        if (Instruction* v = getVerification(info, getSancusModuleInfo(callee),
                                             *f.getParent()))
        {
            verifications[inst] = v;
        }

        Function* stub = getStub(f, *callee);
        cs.setCalledFunction(stub);

        if (stub != callee)
            modified = true;
    }

    for (auto pair : verifications)
        pair.second->insertBefore(pair.first);

    for (auto pair : replacements)
    {
        auto oldInst = pair.first;
        auto newInst = pair.second;
        newInst->insertBefore(oldInst);
        oldInst->replaceAllUsesWith(newInst);
        oldInst->eraseFromParent();
    }

    return modified;
}