Exemplo n.º 1
0
string
Alien::toXML(uint oFlags) const
{
  string self = ANode::toXML(oFlags)
    + " f" + MakeAttrStr(m_filenm) + " n" + MakeAttrStr(m_displaynm);
  self = self + " " + XMLLineRange(oFlags) + " " + XMLVMAIntervals(oFlags);

  // add information on the function definition
  // If the alien has an ancestor and the same procedure definition exists,
  // we'll add an attribute 'ln' to point to the ID of the function definition.
  // This is needed to inform hpcprof that the alien shouldn't be considered
  // as different function.
  
  // 1a: get the load module of the alien
  LM   *lm   = ancestorLM();

  // 1b: check if the alien has the file pointer to its definition
  File *file = lm->findFile(m_filenm);
  if (file) {
    
    // 2: check if there's the same procedure name in the file
    Proc *proc = file->findProc(m_displaynm);
    
    if (proc) {
#if 0
      // 3: check if alien's line range is within the function definition
      bool inc = SrcFile::include(proc->begLine(), proc->endLine(), begLine(), endLine());
      if (inc) {
	// 4: add the link attribute to the function definition
      	self = self + " ln" + xml::MakeAttrStr(StrUtil::toStr(proc->id())); 
      }
#endif
      self = self + " ln" + xml::MakeAttrStr(StrUtil::toStr(proc->id())); 
    }
  }
  return self;
}
Exemplo n.º 2
0
void
BinUtil::TextSeg::ctor_initProcs()
{
  Dbg::LM* dbgInfo = m_lm->getDebugInfo();

  // Any procedure with a parent has a <Proc*, parentVMA> entry
  std::map<Proc*, VMA> parentMap;
  
  // ------------------------------------------------------------
  // Each text section finds and creates its own routines.
  // Traverse the symbol table (which is sorted by VMA) searching
  // for function symbols in our section.  Create a Proc for
  // each one found.
  //
  // Note that symbols can appear multiple times (e.g. a weak symbol
  // 'sbrk' along with a gloabl symbol '__sbrk'), but we should not
  // have multiple procedures.
  // ------------------------------------------------------------

  bfd* abfd = m_lm->abfd();
  asymbol** symtab = m_lm->bfdSymTab(); // sorted
  uint symtabSz = m_lm->bfdSymTabSz();

  // FIXME:PERF: exploit sortedness of 'symtab' to start iteration
  for (uint i = 0; i < symtabSz; i++) {
    asymbol* sym = symtab[i];
    if (isIn(bfd_asymbol_value(sym)) && Proc::isProcBFDSym(sym)) {
      // NOTE: initially we have [begVMA, endVMA) where endVMA is the
      // *end* of the last insn.  This is changed after decoding below.
      VMA begVMA = bfd_asymbol_value(sym);
      VMA endVMA = 0; 
      
      Proc::Type procType;
      if (sym->flags & BSF_LOCAL) {
        procType = Proc::Local;
      }
      else if (sym->flags & BSF_WEAK) {
        procType = Proc::Weak;
      }
      else if (sym->flags & BSF_GLOBAL) {
        procType = Proc::Global;
      }
      else {
        procType = Proc::Unknown;
      }
      
      Proc* proc = m_lm->findProc(begVMA);
      if (proc) {
	DIAG_Assert(proc->begVMA() == begVMA, "TextSeg::ctor_initProcs: Procedure beginning at 0x" << hex << begVMA << " overlaps with:\n" << proc->toString());
	if (procType == Proc::Global) {
	  // 'global' types take precedence
	  proc->type(procType);
	}
	continue;
      }
      
      // Create a procedure based on best information we have.  We
      // always prefer explicit debug information over that inferred
      // from the symbol table.
      string procNm;
      string symNm = bfd_asymbol_name(sym);

      Dbg::LM::iterator it = dbgInfo->find(begVMA);
      Dbg::Proc* dbg = (it != dbgInfo->end()) ? it->second : NULL;

      if (!dbg) {
	procNm = findProcName(abfd, sym);
	string pnm = BinUtil::canonicalizeProcName(procNm);
	
	Dbg::LM::iterator1 it1 = dbgInfo->find1(pnm);
	dbg = (it1 != dbgInfo->end1()) ? it1->second : NULL;
      }
      if (!dbg) {
	Dbg::LM::iterator1 it1 = dbgInfo->find1(symNm);
	dbg = (it1 != dbgInfo->end1()) ? it1->second : NULL;
      }
      
      // Finding the end VMA (end of last insn).  The computation is
      // as follows because sometimes the debug information is
      // *wrong*. (Intel 9 has generated significant over-estimates).
      //
      // N.B. exploits the fact that the symbol table is sorted by vma
      VMA endVMA_approx = findProcEnd(i);

      if (dbg) {
	if (!dbg->name.empty()) {
	  procNm = dbg->name;
	}
	else if (!symNm.empty()) {
          // sometimes a procedure name is in the symbol table even
          // though it is not in the dwarf section. this case occurs
          // when gcc outlines routines from OpenMP parallel sections.
          procNm = symNm;
  	}

#if 1
	// Remove capability below... the DWARF sizes can be wrong!!
	endVMA = endVMA_approx;
#else
	endVMA = std::min(dbg->endVMA, endVMA_approx);
	if (endVMA != endVMA_approx) {
	  int64_t diff = endVMA - endVMA_approx;
	  DIAG_DevMsg(0, procNm << ": inconsistent end VMA: " << diff << " [" << std::showbase << std::hex << begVMA << "-" << endVMA << "/" << endVMA_approx << std::dec << "]");
	}
#endif
      }
      if (!dbg || endVMA == 0) {
	endVMA = endVMA_approx;
      }
      uint size = endVMA - begVMA;

      if (size == 0) {
	continue;
      }
      
      // We now have a valid procedure.  Initilize with [begVMA, endVMA),
      // but note this is changed after disassembly.
      proc = new Proc(this, procNm, symNm, procType, begVMA, endVMA, size);
      m_procs.push_back(proc);
      m_lm->insertProc(VMAInterval(begVMA, endVMA), proc);

      // Add symbolic info
      if (dbg) {
	proc->filename(dbg->filenm);
	proc->begLine(dbg->begLine);
	if (dbg->parent) {
	  parentMap.insert(std::make_pair(proc, dbg->parent->begVMA));
	}
      }
    }
  }

  // ------------------------------------------------------------
  //  If a text section does not have any function symbols, consider
  //  the whole section a quasi procedure
  // ------------------------------------------------------------
  if (numProcs() == 0) {
    // [begVMA, endVMA)
    Proc* proc = new Proc(this, name(), name(), Proc::Quasi, 
			  begVMA(), endVMA(), size());
    m_procs.push_back(proc);
    m_lm->insertProc(VMAInterval(begVMA(), endVMA()), proc);
  }


  // ------------------------------------------------------------
  // Embed parent information
  // ------------------------------------------------------------
  for (std::map<Proc*, VMA>::iterator it = parentMap.begin(); 
       it != parentMap.end(); ++it) {
    Proc* child = it->first;
    VMA parentVMA = it->second;
    Proc* parent = m_lm->findProc(parentVMA);
    DIAG_AssertWarn(parent, "Could not find parent within this section:\n" 
		    << child->toString());
    if (parent == child) {
      DIAG_WMsg(0, "Procedure has itself as parent!\n" << child->toString());
      continue; // skip
    }
    child->parent(parent);
  }
}