コード例 #1
0
ファイル: DWARFVerifier.cpp プロジェクト: Lucretia/llvm
unsigned DWARFVerifier::verifyNameIndexEntries(
    const DWARFDebugNames::NameIndex &NI,
    const DWARFDebugNames::NameTableEntry &NTE) {
  // Verifying type unit indexes not supported.
  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
    return 0;

  const char *CStr = NTE.getString();
  if (!CStr) {
    error() << formatv(
        "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
        NI.getUnitOffset(), NTE.getIndex());
    return 1;
  }
  StringRef Str(CStr);

  unsigned NumErrors = 0;
  unsigned NumEntries = 0;
  uint32_t EntryID = NTE.getEntryOffset();
  uint32_t NextEntryID = EntryID;
  Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
  for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
                                EntryOr = NI.getEntry(&NextEntryID)) {
    uint32_t CUIndex = *EntryOr->getCUIndex();
    if (CUIndex > NI.getCUCount()) {
      error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
                         "invalid CU index ({2}).\n",
                         NI.getUnitOffset(), EntryID, CUIndex);
      ++NumErrors;
      continue;
    }
    uint32_t CUOffset = NI.getCUOffset(CUIndex);
    uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
    DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
    if (!DIE) {
      error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
                         "non-existing DIE @ {2:x}.\n",
                         NI.getUnitOffset(), EntryID, DIEOffset);
      ++NumErrors;
      continue;
    }
    if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
      error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
                         "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
                         NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
                         DIE.getDwarfUnit()->getOffset());
      ++NumErrors;
    }
    if (DIE.getTag() != EntryOr->tag()) {
      error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
                         "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
                         NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
                         DIE.getTag());
      ++NumErrors;
    }

    auto EntryNames = getNames(DIE);
    if (!is_contained(EntryNames, Str)) {
      error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
                         "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
                         NI.getUnitOffset(), EntryID, DIEOffset, Str,
                         make_range(EntryNames.begin(), EntryNames.end()));
      ++NumErrors;
    }
  }
  handleAllErrors(EntryOr.takeError(),
                  [&](const DWARFDebugNames::SentinelError &) {
                    if (NumEntries > 0)
                      return;
                    error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
                                       "not associated with any entries.\n",
                                       NI.getUnitOffset(), NTE.getIndex(), Str);
                    ++NumErrors;
                  },
                  [&](const ErrorInfoBase &Info) {
                    error()
                        << formatv("Name Index @ {0:x}: Name {1} ({2}): {3}\n",
                                   NI.getUnitOffset(), NTE.getIndex(), Str,
                                   Info.message());
                    ++NumErrors;
                  });
  return NumErrors;
}