当前位置: 首页>>代码示例>>C++>>正文


C++ DWARFDataExtractor::getU16方法代码示例

本文整理汇总了C++中DWARFDataExtractor::getU16方法的典型用法代码示例。如果您正苦于以下问题:C++ DWARFDataExtractor::getU16方法的具体用法?C++ DWARFDataExtractor::getU16怎么用?C++ DWARFDataExtractor::getU16使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在DWARFDataExtractor的用法示例。


在下文中一共展示了DWARFDataExtractor::getU16方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1:

// Look for a DWARF32-formatted contribution to the string offsets table
// starting at a given offset and record it in a descriptor.
static Optional<StrOffsetsContributionDescriptor>
parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
  if (!DA.isValidOffsetForDataOfSize(Offset, 8))
    return None;
  uint32_t ContributionSize = DA.getU32(&Offset);
  if (ContributionSize >= 0xfffffff0)
    return None;
  uint8_t Version = DA.getU16(&Offset);
  (void)DA.getU16(&Offset); // padding
  // The encoded length includes the 2-byte version field and the 2-byte
  // padding, so we need to subtract them out when we populate the descriptor.
  return {{Offset, ContributionSize - 4, Version, DWARF32}};
}
开发者ID:MatzeB,项目名称:llvm,代码行数:15,代码来源:DWARFUnit.cpp

示例2: success

llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
                                             uint32_t *Offset) {
  // Check that we can read the fixed-size part.
  if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1))
    return make_error<StringError>("Section too small: cannot read header.",
                                   inconvertibleErrorCode());

  UnitLength = AS.getU32(Offset);
  Version = AS.getU16(Offset);
  Padding = AS.getU16(Offset);
  CompUnitCount = AS.getU32(Offset);
  LocalTypeUnitCount = AS.getU32(Offset);
  ForeignTypeUnitCount = AS.getU32(Offset);
  BucketCount = AS.getU32(Offset);
  NameCount = AS.getU32(Offset);
  AbbrevTableSize = AS.getU32(Offset);
  AugmentationStringSize = AS.getU32(Offset);

  if (!AS.isValidOffsetForDataOfSize(*Offset, AugmentationStringSize))
    return make_error<StringError>(
        "Section too small: cannot read header augmentation.",
        inconvertibleErrorCode());
  AugmentationString.resize(AugmentationStringSize);
  AS.getU8(Offset, reinterpret_cast<uint8_t *>(AugmentationString.data()),
           AugmentationStringSize);
  *Offset = alignTo(*Offset, 4);
  return Error::success();
}
开发者ID:franchiotta,项目名称:llvm,代码行数:28,代码来源:DWARFAcceleratorTable.cpp

示例3: StrOffsetsContributionDescriptor

// Look for a DWARF64-formatted contribution to the string offsets table
// starting at a given offset and record it in a descriptor.
static Optional<StrOffsetsContributionDescriptor>
parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
  if (!DA.isValidOffsetForDataOfSize(Offset, 16))
    return Optional<StrOffsetsContributionDescriptor>();

  if (DA.getU32(&Offset) != 0xffffffff)
    return Optional<StrOffsetsContributionDescriptor>();

  uint64_t Size = DA.getU64(&Offset);
  uint8_t Version = DA.getU16(&Offset);
  (void)DA.getU16(&Offset); // padding
  // The encoded length includes the 2-byte version field and the 2-byte
  // padding, so we need to subtract them out when we populate the descriptor.
  return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
  //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
}
开发者ID:Lucretia,项目名称:llvm,代码行数:18,代码来源:DWARFUnit.cpp

示例4: while

Optional<DWARFDebugLoc::LocationList>
DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) {
  LocationList LL;
  LL.Offset = *Offset;

  // 2.6.2 Location Lists
  // A location list entry consists of:
  while (true) {
    Entry E;
    if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) {
      llvm::errs() << "Location list overflows the debug_loc section.\n";
      return None;
    }

    // 1. A beginning address offset. ...
    E.Begin = Data.getRelocatedAddress(Offset);

    // 2. An ending address offset. ...
    E.End = Data.getRelocatedAddress(Offset);

    // The end of any given location list is marked by an end of list entry,
    // which consists of a 0 for the beginning address offset and a 0 for the
    // ending address offset.
    if (E.Begin == 0 && E.End == 0)
      return LL;

    if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) {
      llvm::errs() << "Location list overflows the debug_loc section.\n";
      return None;
    }

    unsigned Bytes = Data.getU16(Offset);
    if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) {
      llvm::errs() << "Location list overflows the debug_loc section.\n";
      return None;
    }
    // A single location description describing the location of the object...
    StringRef str = Data.getData().substr(*Offset, Bytes);
    *Offset += Bytes;
    E.Loc.reserve(str.size());
    std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
    LL.Entries.push_back(std::move(E));
  }
}
开发者ID:a565109863,项目名称:src,代码行数:44,代码来源:DWARFDebugLoc.cpp

示例5: verifyUnitHeader

bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
                                     uint32_t *Offset, unsigned UnitIndex,
                                     uint8_t &UnitType, bool &isUnitDWARF64) {
  uint32_t AbbrOffset, Length;
  uint8_t AddrSize = 0;
  uint16_t Version;
  bool Success = true;

  bool ValidLength = false;
  bool ValidVersion = false;
  bool ValidAddrSize = false;
  bool ValidType = true;
  bool ValidAbbrevOffset = true;

  uint32_t OffsetStart = *Offset;
  Length = DebugInfoData.getU32(Offset);
  if (Length == UINT32_MAX) {
    isUnitDWARF64 = true;
    OS << format(
        "Unit[%d] is in 64-bit DWARF format; cannot verify from this point.\n",
        UnitIndex);
    return false;
  }
  Version = DebugInfoData.getU16(Offset);

  if (Version >= 5) {
    UnitType = DebugInfoData.getU8(Offset);
    AddrSize = DebugInfoData.getU8(Offset);
    AbbrOffset = DebugInfoData.getU32(Offset);
    ValidType = dwarf::isUnitType(UnitType);
  } else {
    UnitType = 0;
    AbbrOffset = DebugInfoData.getU32(Offset);
    AddrSize = DebugInfoData.getU8(Offset);
  }

  if (!DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset))
    ValidAbbrevOffset = false;

  ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
  ValidVersion = DWARFContext::isSupportedVersion(Version);
  ValidAddrSize = AddrSize == 4 || AddrSize == 8;
  if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
      !ValidType) {
    Success = false;
    error() << format("Units[%d] - start offset: 0x%08x \n", UnitIndex,
                      OffsetStart);
    if (!ValidLength)
      note() << "The length for this unit is too "
            "large for the .debug_info provided.\n";
    if (!ValidVersion)
      note() << "The 16 bit unit header version is not valid.\n";
    if (!ValidType)
      note() << "The unit type encoding is not valid.\n";
    if (!ValidAbbrevOffset)
      note() << "The offset into the .debug_abbrev section is "
            "not valid.\n";
    if (!ValidAddrSize)
      note() << "The address size is unsupported.\n";
  }
  *Offset = OffsetStart + Length + 4;
  return Success;
}
开发者ID:franchiotta,项目名称:llvm,代码行数:63,代码来源:DWARFVerifier.cpp

示例6: extractValue

bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
                                  uint32_t *OffsetPtr, DWARFFormParams FP,
                                  const DWARFUnit *CU) {
  U = CU;
  bool Indirect = false;
  bool IsBlock = false;
  Value.data = nullptr;
  // Read the value for the form into value and follow and DW_FORM_indirect
  // instances we run into
  do {
    Indirect = false;
    switch (Form) {
    case DW_FORM_addr:
    case DW_FORM_ref_addr: {
      uint16_t Size =
          (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
      Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
      break;
    }
    case DW_FORM_exprloc:
    case DW_FORM_block:
      Value.uval = Data.getULEB128(OffsetPtr);
      IsBlock = true;
      break;
    case DW_FORM_block1:
      Value.uval = Data.getU8(OffsetPtr);
      IsBlock = true;
      break;
    case DW_FORM_block2:
      Value.uval = Data.getU16(OffsetPtr);
      IsBlock = true;
      break;
    case DW_FORM_block4:
      Value.uval = Data.getU32(OffsetPtr);
      IsBlock = true;
      break;
    case DW_FORM_data1:
    case DW_FORM_ref1:
    case DW_FORM_flag:
    case DW_FORM_strx1:
    case DW_FORM_addrx1:
      Value.uval = Data.getU8(OffsetPtr);
      break;
    case DW_FORM_data2:
    case DW_FORM_ref2:
    case DW_FORM_strx2:
    case DW_FORM_addrx2:
      Value.uval = Data.getU16(OffsetPtr);
      break;
    case DW_FORM_strx3:
      Value.uval = Data.getU24(OffsetPtr);
      break;
    case DW_FORM_data4:
    case DW_FORM_ref4:
    case DW_FORM_ref_sup4:
    case DW_FORM_strx4:
    case DW_FORM_addrx4:
      Value.uval = Data.getRelocatedValue(4, OffsetPtr);
      break;
    case DW_FORM_data8:
    case DW_FORM_ref8:
    case DW_FORM_ref_sup8:
      Value.uval = Data.getU64(OffsetPtr);
      break;
    case DW_FORM_data16:
      // Treat this like a 16-byte block.
      Value.uval = 16;
      IsBlock = true;
      break;
    case DW_FORM_sdata:
      Value.sval = Data.getSLEB128(OffsetPtr);
      break;
    case DW_FORM_udata:
    case DW_FORM_ref_udata:
      Value.uval = Data.getULEB128(OffsetPtr);
      break;
    case DW_FORM_string:
      Value.cstr = Data.getCStr(OffsetPtr);
      break;
    case DW_FORM_indirect:
      Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
      Indirect = true;
      break;
    case DW_FORM_strp:
    case DW_FORM_sec_offset:
    case DW_FORM_GNU_ref_alt:
    case DW_FORM_GNU_strp_alt:
    case DW_FORM_line_strp:
    case DW_FORM_strp_sup: {
      Value.uval =
          Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
      break;
    }
    case DW_FORM_flag_present:
      Value.uval = 1;
      break;
    case DW_FORM_ref_sig8:
      Value.uval = Data.getU64(OffsetPtr);
      break;
    case DW_FORM_GNU_addr_index:
//.........这里部分代码省略.........
开发者ID:a565109863,项目名称:src,代码行数:101,代码来源:DWARFFormValue.cpp

示例7: extract

bool DWARFUnitHeader::extract(DWARFContext &Context,
                              const DWARFDataExtractor &debug_info,
                              uint32_t *offset_ptr,
                              DWARFSectionKind SectionKind,
                              const DWARFUnitIndex *Index) {
  Offset = *offset_ptr;
  IndexEntry = Index ? Index->getFromOffset(*offset_ptr) : nullptr;
  Length = debug_info.getU32(offset_ptr);
  // FIXME: Support DWARF64.
  unsigned SizeOfLength = 4;
  FormParams.Format = DWARF32;
  FormParams.Version = debug_info.getU16(offset_ptr);
  if (FormParams.Version >= 5) {
    UnitType = debug_info.getU8(offset_ptr);
    FormParams.AddrSize = debug_info.getU8(offset_ptr);
    AbbrOffset = debug_info.getU32(offset_ptr);
  } else {
    AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr);
    FormParams.AddrSize = debug_info.getU8(offset_ptr);
    // Fake a unit type based on the section type.  This isn't perfect,
    // but distinguishing compile and type units is generally enough.
    if (SectionKind == DW_SECT_TYPES)
      UnitType = DW_UT_type;
    else
      UnitType = DW_UT_compile;
  }
  if (IndexEntry) {
    if (AbbrOffset)
      return false;
    auto *UnitContrib = IndexEntry->getOffset();
    if (!UnitContrib || UnitContrib->Length != (Length + 4))
      return false;
    auto *AbbrEntry = IndexEntry->getOffset(DW_SECT_ABBREV);
    if (!AbbrEntry)
      return false;
    AbbrOffset = AbbrEntry->Offset;
  }
  if (isTypeUnit()) {
    TypeHash = debug_info.getU64(offset_ptr);
    TypeOffset = debug_info.getU32(offset_ptr);
  } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
    DWOId = debug_info.getU64(offset_ptr);

  // Header fields all parsed, capture the size of this unit header.
  assert(*offset_ptr - Offset <= 255 && "unexpected header size");
  Size = uint8_t(*offset_ptr - Offset);

  // Type offset is unit-relative; should be after the header and before
  // the end of the current unit.
  bool TypeOffsetOK =
      !isTypeUnit()
          ? true
          : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
  bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
  bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
  bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;

  if (!LengthOK || !VersionOK || !AddrSizeOK || !TypeOffsetOK)
    return false;

  // Keep track of the highest DWARF version we encounter across all units.
  Context.setMaxVersionIfGreater(getVersion());
  return true;
}
开发者ID:Lucretia,项目名称:llvm,代码行数:64,代码来源:DWARFUnit.cpp

示例8: State


//.........这里部分代码省略.........
        // Takes no arguments. Add to the address register of the state
        // machine the address increment value corresponding to special
        // opcode 255. The motivation for DW_LNS_const_add_pc is this:
        // when the statement program needs to advance the address by a
        // small amount, it can use a single special opcode, which occupies
        // a single byte. When it needs to advance the address by up to
        // twice the range of the last special opcode, it can use
        // DW_LNS_const_add_pc followed by a special opcode, for a total
        // of two bytes. Only if it needs to advance the address by more
        // than twice that range will it need to use both DW_LNS_advance_pc
        // and a special opcode, requiring three or more bytes.
        {
          uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
          uint64_t AddrOffset =
              (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
          State.Row.Address += AddrOffset;
          if (OS)
            *OS
                << format(" (0x%16.16" PRIx64 ")", AddrOffset);
        }
        break;

      case DW_LNS_fixed_advance_pc:
        // Takes a single uhalf operand. Add to the address register of
        // the state machine the value of the (unencoded) operand. This
        // is the only extended opcode that takes an argument that is not
        // a variable length number. The motivation for DW_LNS_fixed_advance_pc
        // is this: existing assemblers cannot emit DW_LNS_advance_pc or
        // special opcodes because they cannot encode LEB128 numbers or
        // judge when the computation of a special opcode overflows and
        // requires the use of DW_LNS_advance_pc. Such assemblers, however,
        // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
        {
          uint16_t PCOffset = DebugLineData.getU16(OffsetPtr);
          State.Row.Address += PCOffset;
          if (OS)
            *OS
                << format(" (0x%16.16" PRIx64 ")", PCOffset);
        }
        break;

      case DW_LNS_set_prologue_end:
        // Takes no arguments. Set the prologue_end register of the
        // state machine to true
        State.Row.PrologueEnd = true;
        break;

      case DW_LNS_set_epilogue_begin:
        // Takes no arguments. Set the basic_block register of the
        // state machine to true
        State.Row.EpilogueBegin = true;
        break;

      case DW_LNS_set_isa:
        // Takes a single unsigned LEB128 operand and stores it in the
        // column register of the state machine.
        State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
        if (OS)
          *OS << " (" << State.Row.Isa << ")";
        break;

      default:
        // Handle any unknown standard opcodes here. We know the lengths
        // of such opcodes because they are specified in the prologue
        // as a multiple of LEB128 operands for each opcode.
        {
开发者ID:BNieuwenhuizen,项目名称:llvm,代码行数:67,代码来源:DWARFDebugLine.cpp

示例9: clear

bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
                                     uint32_t *OffsetPtr, const DWARFUnit *U) {
  const uint64_t PrologueOffset = *OffsetPtr;

  clear();
  TotalLength = DebugLineData.getU32(OffsetPtr);
  if (TotalLength == UINT32_MAX) {
    FormParams.Format = dwarf::DWARF64;
    TotalLength = DebugLineData.getU64(OffsetPtr);
  } else if (TotalLength >= 0xffffff00) {
    return false;
  }
  FormParams.Version = DebugLineData.getU16(OffsetPtr);
  if (getVersion() < 2)
    return false;

  if (getVersion() >= 5) {
    FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
    assert((DebugLineData.getAddressSize() == 0 ||
            DebugLineData.getAddressSize() == getAddressSize()) &&
           "Line table header and data extractor disagree");
    SegSelectorSize = DebugLineData.getU8(OffsetPtr);
  }

  PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
  const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
  MinInstLength = DebugLineData.getU8(OffsetPtr);
  if (getVersion() >= 4)
    MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
  DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
  LineBase = DebugLineData.getU8(OffsetPtr);
  LineRange = DebugLineData.getU8(OffsetPtr);
  OpcodeBase = DebugLineData.getU8(OffsetPtr);

  StandardOpcodeLengths.reserve(OpcodeBase - 1);
  for (uint32_t I = 1; I < OpcodeBase; ++I) {
    uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
    StandardOpcodeLengths.push_back(OpLen);
  }

  if (getVersion() >= 5) {
    if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
                              FormParams, U, HasMD5, IncludeDirectories,
                              FileNames)) {
      fprintf(stderr,
              "warning: parsing line table prologue at 0x%8.8" PRIx64
              " found an invalid directory or file table description at"
              " 0x%8.8" PRIx64 "\n", PrologueOffset, (uint64_t)*OffsetPtr);
      return false;
    }
  } else
    parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
                         IncludeDirectories, FileNames);

  if (*OffsetPtr != EndPrologueOffset) {
    fprintf(stderr,
            "warning: parsing line table prologue at 0x%8.8" PRIx64
            " should have ended at 0x%8.8" PRIx64
            " but it ended at 0x%8.8" PRIx64 "\n",
            PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
    return false;
  }
  return true;
}
开发者ID:BNieuwenhuizen,项目名称:llvm,代码行数:64,代码来源:DWARFDebugLine.cpp

示例10: createStringError

Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
                                      uint32_t *OffsetPtr,
                                      const DWARFContext &Ctx,
                                      const DWARFUnit *U) {
  const uint64_t PrologueOffset = *OffsetPtr;

  clear();
  TotalLength = DebugLineData.getU32(OffsetPtr);
  if (TotalLength == UINT32_MAX) {
    FormParams.Format = dwarf::DWARF64;
    TotalLength = DebugLineData.getU64(OffsetPtr);
  } else if (TotalLength >= 0xffffff00) {
    return createStringError(errc::invalid_argument,
        "parsing line table prologue at offset 0x%8.8" PRIx64
        " unsupported reserved unit length found of value 0x%8.8" PRIx64,
        PrologueOffset, TotalLength);
  }
  FormParams.Version = DebugLineData.getU16(OffsetPtr);
  if (getVersion() < 2)
    return createStringError(errc::not_supported,
                       "parsing line table prologue at offset 0x%8.8" PRIx64
                       " found unsupported version 0x%2.2" PRIx16,
                       PrologueOffset, getVersion());

  if (getVersion() >= 5) {
    FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
    assert((DebugLineData.getAddressSize() == 0 ||
            DebugLineData.getAddressSize() == getAddressSize()) &&
           "Line table header and data extractor disagree");
    SegSelectorSize = DebugLineData.getU8(OffsetPtr);
  }

  PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
  const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
  MinInstLength = DebugLineData.getU8(OffsetPtr);
  if (getVersion() >= 4)
    MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
  DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
  LineBase = DebugLineData.getU8(OffsetPtr);
  LineRange = DebugLineData.getU8(OffsetPtr);
  OpcodeBase = DebugLineData.getU8(OffsetPtr);

  StandardOpcodeLengths.reserve(OpcodeBase - 1);
  for (uint32_t I = 1; I < OpcodeBase; ++I) {
    uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
    StandardOpcodeLengths.push_back(OpLen);
  }

  if (getVersion() >= 5) {
    if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
                              FormParams, Ctx, U, ContentTypes,
                              IncludeDirectories, FileNames)) {
      return createStringError(errc::invalid_argument,
          "parsing line table prologue at 0x%8.8" PRIx64
          " found an invalid directory or file table description at"
          " 0x%8.8" PRIx64,
          PrologueOffset, (uint64_t)*OffsetPtr);
    }
  } else
    parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
                         ContentTypes, IncludeDirectories, FileNames);

  if (*OffsetPtr != EndPrologueOffset)
    return createStringError(errc::invalid_argument,
                       "parsing line table prologue at 0x%8.8" PRIx64
                       " should have ended at 0x%8.8" PRIx64
                       " but it ended at 0x%8.8" PRIx64,
                       PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
  return Error::success();
}
开发者ID:jamboree,项目名称:llvm,代码行数:70,代码来源:DWARFDebugLine.cpp


注:本文中的DWARFDataExtractor::getU16方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。