Beispiel #1
0
// Walk through the buckets and emit the full data for each element in
// the bucket. For the string case emit the dies and the various offsets.
// Terminate each HashData bucket with 0.
void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) {
  for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
    uint64_t PrevHash = UINT64_MAX;
    for (HashList::const_iterator HI = Buckets[i].begin(),
                                  HE = Buckets[i].end();
         HI != HE; ++HI) {
      // Terminate the previous entry if there is no hash collision
      // with the current one.
      if (PrevHash != UINT64_MAX && PrevHash != (*HI)->HashValue)
        Asm->EmitInt32(0);
      // Remember to emit the label for our offset.
      Asm->OutStreamer->EmitLabel((*HI)->Sym);
      Asm->OutStreamer->AddComment((*HI)->Str);
      Asm->emitDwarfStringOffset((*HI)->Data.Name);
      Asm->OutStreamer->AddComment("Num DIEs");
      Asm->EmitInt32((*HI)->Data.Values.size());
      for (HashDataContents *HD : (*HI)->Data.Values) {
        // Emit the DIE offset
        DwarfCompileUnit *CU = D->lookupUnit(HD->Die->getUnit());
        assert(CU && "Accelerated DIE should belong to a CU.");
        Asm->EmitInt32(HD->Die->getOffset() + CU->getDebugInfoOffset());
        // If we have multiple Atoms emit that info too.
        // FIXME: A bit of a hack, we either emit only one atom or all info.
        if (HeaderData.Atoms.size() > 1) {
          Asm->EmitInt16(HD->Die->getTag());
          Asm->EmitInt8(HD->Flags);
        }
      }
      PrevHash = (*HI)->HashValue;
    }
    // Emit the final end marker for the bucket.
    if (!Buckets[i].empty())
      Asm->EmitInt32(0);
  }
}
Beispiel #2
0
// Walk through the buckets and emit the full data for each element in
// the bucket. For the string case emit the dies and the various offsets.
// Terminate each HashData bucket with 0.
void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D,
                               MCSymbol *StrSym) {
  uint64_t PrevHash = UINT64_MAX;
  for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
    for (HashList::const_iterator HI = Buckets[i].begin(),
                                  HE = Buckets[i].end();
         HI != HE; ++HI) {
      // Remember to emit the label for our offset.
      Asm->OutStreamer.EmitLabel((*HI)->Sym);
      Asm->OutStreamer.AddComment((*HI)->Str);
      Asm->EmitSectionOffset((*HI)->Data.StrSym, StrSym);
      Asm->OutStreamer.AddComment("Num DIEs");
      Asm->EmitInt32((*HI)->Data.Values.size());
      for (HashDataContents *HD : (*HI)->Data.Values) {
        // Emit the DIE offset
        DwarfCompileUnit *CU = D->lookupUnit(HD->Die->getUnit());
        assert(CU && "Accelerated DIE should belong to a CU.");
        Asm->EmitInt32(HD->Die->getOffset() + CU->getDebugInfoOffset());
        // If we have multiple Atoms emit that info too.
        // FIXME: A bit of a hack, we either emit only one atom or all info.
        if (HeaderData.Atoms.size() > 1) {
          Asm->EmitInt16(HD->Die->getTag());
          Asm->EmitInt8(HD->Flags);
        }
      }
      // Emit a 0 to terminate the data unless we have a hash collision.
      if (PrevHash != (*HI)->HashValue)
        Asm->EmitInt32(0);
      PrevHash = (*HI)->HashValue;
    }
  }
}
Beispiel #3
0
/// EmitValue - Emit debug information entry offset.
///
void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {

  if (Form == dwarf::DW_FORM_ref_addr) {
    const DwarfDebug *DD = AP->getDwarfDebug();
    unsigned Addr = Entry->getOffset();
    assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations.");
    // For DW_FORM_ref_addr, output the offset from beginning of debug info
    // section. Entry->getOffset() returns the offset from start of the
    // compile unit.
    DwarfCompileUnit *CU = DD->lookupUnit(Entry->getUnit());
    assert(CU && "CUDie should belong to a CU.");
    Addr += CU->getDebugInfoOffset();
    if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
      AP->EmitLabelPlusOffset(CU->getSectionSym(), Addr,
                              DIEEntry::getRefAddrSize(AP));
    else
      AP->OutStreamer->EmitIntValue(Addr, DIEEntry::getRefAddrSize(AP));
  } else
    AP->EmitInt32(Entry->getOffset());
}
Beispiel #4
0
void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
    LexicalScope *Scope) {
  DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
  if (AbsDef)
    return;

  auto *SP = cast<DISubprogram>(Scope->getScopeNode());

  DIE *ContextDIE;
  DwarfCompileUnit *ContextCU = this;

  if (includeMinimalInlineScopes())
    ContextDIE = &getUnitDie();
  // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
  // the important distinction that the debug node is not associated with the
  // DIE (since the debug node will be associated with the concrete DIE, if
  // any). It could be refactored to some common utility function.
  else if (auto *SPDecl = SP->getDeclaration()) {
    ContextDIE = &getUnitDie();
    getOrCreateSubprogramDIE(SPDecl);
  } else {
    ContextDIE = getOrCreateContextDIE(resolve(SP->getScope()));
    // The scope may be shared with a subprogram that has already been
    // constructed in another CU, in which case we need to construct this
    // subprogram in the same CU.
    ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
  }

  // Passing null as the associated node because the abstract definition
  // shouldn't be found by lookup.
  AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
  ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);

  if (!ContextCU->includeMinimalInlineScopes())
    ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
  if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
    ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
}
// Walk through the buckets and emit the full data for each element in
// the bucket. For the string case emit the dies and the various offsets.
// Terminate each HashData bucket with 0.
void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) {
  assert(!(UseDieOffsets && D));
  for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
    uint64_t PrevHash = UINT64_MAX;
    for (HashList::const_iterator HI = Buckets[i].begin(),
                                  HE = Buckets[i].end();
         HI != HE; ++HI) {
      // Terminate the previous entry if there is no hash collision
      // with the current one.
      if (PrevHash != UINT64_MAX && PrevHash != (*HI)->HashValue)
        Asm->EmitInt32(0);
      // Remember to emit the label for our offset.
      Asm->OutStreamer.EmitLabel((*HI)->Sym);
      Asm->OutStreamer.AddComment((*HI)->Str);
      if (UseStringOffsets)
        Asm->EmitInt32((*HI)->Data.StrOffset);
      else
        Asm->emitSectionOffset((*HI)->Data.StrSym);
      Asm->OutStreamer.AddComment("Num DIEs");
      Asm->EmitInt32((*HI)->Data.Values.size());
      for (HashDataContents *HD : (*HI)->Data.Values) {
	if (HD->isDIE()) {
          // Emit the DIE offset
          uint32_t Offset;
          if (UseDieOffsets) {
            Offset = HD->DieOffset;
          } else {
            DwarfCompileUnit *CU = D->lookupUnit(HD->Die->getUnit());
            assert(CU && "Accelerated DIE should belong to a CU.");
            Offset = HD->Die->getOffset() + CU->getDebugInfoOffset();
          }
	  Asm->EmitInt32(Offset);
	  // If we have multiple Atoms emit that info too.
	  unsigned AtomOffset = 0;
          for (const auto &Atom : makeArrayRef(HeaderData.Atoms.data() + 1,
                                               HeaderData.Atoms.size() - 1)) {
            switch (Atom.form) {
            case dwarf::DW_FORM_data1:
              Asm->EmitInt8(HD->getAtom<uint8_t>(AtomOffset));
              AtomOffset += 1;
              break;
            case dwarf::DW_FORM_data2:
              Asm->EmitInt16(HD->getAtom<uint16_t>(AtomOffset));
              AtomOffset += 2;
              break;
            case dwarf::DW_FORM_data4:
              Asm->EmitInt32(HD->getAtom<uint32_t>(AtomOffset));
              AtomOffset += 4;
              break;
            case dwarf::DW_FORM_data8:
              Asm->OutStreamer.EmitIntValue(HD->getAtom<uint64_t>(AtomOffset), 8);
              AtomOffset += 8;
              break;
            }
          }
	} else
          // Emit the .debug_str offset.
          Asm->emitSectionOffset(HD->Strp);
      }
      PrevHash = (*HI)->HashValue;
    }
    // Emit the final end marker for the bucket.
    if (!Buckets[i].empty())
      Asm->EmitInt32(0);
  }
}