diff --git a/OAT.xml b/OAT.xml index 0407b602a7499c13540996ab6cf9e2a02f9bb065..d9dd34a3fb76bf849e0ca8fa644ca18c9fa22b46 100644 --- a/OAT.xml +++ b/OAT.xml @@ -208,6 +208,8 @@ + + diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 1f3d524691ed61dea0f6d999515e71e7e84f66ff..c5de4d0dfd0822b898a3c73e4f8b5f728c941519 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -6462,6 +6462,95 @@ private: friend class ASTStmtWriter; }; +// OHOS_LOCAL begin +// This represents a use of the __builtin_hm_type_signature, which input a +// Struct. +class HMTypeSigExpr final : public Expr { + SourceLocation OpLoc, RParenLoc; + QualType DataType; + +public: + enum FieldType { PADDING = 0, POINTER = 1, DATA = 2 }; + + UnaryExprOrTypeTrait ExprKind; + + /// Build an empty call expression. + explicit HMTypeSigExpr(EmptyShell Empty) : Expr(HMTypeSigExprClass, Empty) {} + HMTypeSigExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo, + QualType resultType, SourceLocation op, SourceLocation rp); + + FieldType getFieldTypeEnum(QualType FieldTy) const; + UnaryExprOrTypeTrait getKind() const { return ExprKind; } + std::string getFieldTypeStr(FieldType FieldEnum) const { + return std::to_string(FieldEnum); + } + + // The structure is divided into multiple granules in the unit of 8 bytes. Each + // granule may contain multiple FieldTypes, Perform bitwise OR based on the + // contained FieldType to obtain a GranulesValue. signature: The structure + // signature is a character string composed of each GranulesValue. summary: + // Summary of a granule(GranuleSummay)=1<< GranulesValue. The summary of the + // structure is each GranuleSummay bitwise OR. + APValue EvaluateTypeSig(const ASTContext &Ctx) const; + + APValue MakeStringLiteral(StringRef Tmp, const ASTContext &Ctx) const; + bool divideGranulesBase(FieldType CurType, uint64_t fieldSize, + const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesArray(const ArrayType *CurType, const ASTContext &Ctx, + uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesVector(const VectorType *CurType, const ASTContext &Ctx, + uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesRecord(const RecordType *CurType, const ASTContext &Ctx, + uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesUnion(const RecordType *CurType, const ASTContext &Ctx, + uint64_t &GranulesPos, + std::vector> &vec) const; + + /// Return a string representing the name of the specific builtin function. + StringRef getBuiltinStr() const; + APValue getBuiltinResult(const ASTContext &Ctx, std::string signature, + unsigned short summary) const; + QualType getTypeOfArgument() const { return DataType; } + + SourceLocation getOperatorLoc() const LLVM_READONLY { return OpLoc; } + void setOperatorLoc(SourceLocation L) { OpLoc = L; } + + SourceLocation getRParenLoc() const LLVM_READONLY { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return OpLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(child_iterator(), child_iterator()); + } + +private: + // The structure is divided into 8-byte granularities and stored in the + // std::vector> vec container. the outer container is a + // container for all granules, The size of the outer container is the number + // of granules. The inner container is a collection of different types of one + // granule. The process of generating the vector is a recursive invoking + // process. The fields of the structure may also be structures, arrays, or + // basic types. Therefore, the vector needs to be processed recursively. + void divideGranules(QualType CurType, const ASTContext &Ctx, + uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranules(const FieldDecl *Field, const ASTContext &Ctx, + uint64_t &GranulesPos, + std::vector> &vec) const; + + friend class ASTStmtReader; + static const uint64_t GranulesSize = 64; +}; } // end namespace clang +// OHOS_LOCAL end #endif // LLVM_CLANG_AST_EXPR_H diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 6c6d5402d5d12742cdbc69d91f8a34db0dc396ad..0efdd4d8bc15a19b02d2b464a453f0f935a7dee7 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3158,6 +3158,9 @@ DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective, DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(HMTypeSigExpr, {}) //OHOS_LOCAL + // OpenMP clauses. template bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f79e9ef3fa10a963b652222cd951c13efb54559c..19229687de7dea1659b82225f3fdb340e771ebc1 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1759,6 +1759,20 @@ def PacPtrTag : InheritableAttr { let Documentation = [PacPtrTagDocs]; let SimpleHandler = 1; } + +def PacExclTag : InheritableAttr { + let Spellings = [GCC<"pac_excl">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Documentation = [PacExclTagDocs]; + let SimpleHandler = 1; +} + +def PacSeqlTag : InheritableAttr { + let Spellings = [GCC<"pac_seql">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Documentation = [PacSeqlTagDocs]; + let SimpleHandler = 1; +} // OHOS_LOCAL end def ReturnsTwice : InheritableAttr { @@ -2313,6 +2327,17 @@ def OptimizeNone : InheritableAttr { let Documentation = [OptnoneDocs]; } +// OHOS_LOCAL begin +def Optimize : InheritableAttr { + let Spellings = [GCC<"optimize">]; + let Args = [VariadicEnumArgument<"OptAttrs", "OptAttrKind", + ["omit-frame-pointer", "no-omit-frame-pointer"], + ["OmitFramePointer", "NoOmitFramePointer"]>]; + let Subjects = SubjectList<[Function]>; + let Documentation = [OptimizeDocs]; +} +// OHOS_LOCAL end + def Overloadable : Attr { let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 74e76f42e04c95d00d0022d6fd4f778cb1271f51..06dd22833dae8e5290718a48b034da54c2199fef 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1369,6 +1369,22 @@ def PacPtrTagDocs : Documentation { The ``pac_protected_ptr`` attribute asks the compiler to protect the struct pointer type field with PA }]; } + +def PacExclTagDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``pac_excl`` attribute asks the compiler to protect the struct field with PA +by exclusive load/store instructions + }]; +} + +def PacSeqlTagDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``pac_seql`` attribute asks the compiler to protect the struct field with PA +by seqlock method + }]; +} // OHOS_LOCAL end def ObjCRequiresSuperDocs : Documentation { @@ -3493,6 +3509,24 @@ attributes. }]; } +// OHOS_LOCAL begin +def OptimizeDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``optimize`` attribute, when attached to a function, indicates that the +function should be compiled with a different optimization level than specified +on the command line. See the Function Attributes documentation on GCC's docs for +more information. Currently, the attribute differs from GCC in that Clang only +supports one argument, doesn't support ``-f`` arguments, and also doesn't +support expressions or integers as arguments. Clang does not intend to fully +support the GCC semantics. Optimization attributes only "omit-frame-pointer/no-omit-frame-pointer" +are supported. + +Refer to: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + }]; +} +// OHOS_LOCAL end + def LoopHintDocs : Documentation { let Category = DocCatStmt; let Heading = "#pragma clang loop"; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a6531ecf17b313d14f090b6acdff3a51cb797f0f..a6240f32b0339b07473259a33da0ab9b54c28054 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3018,6 +3018,14 @@ def err_attribute_too_many_arguments : Error< "%0 attribute takes no more than %1 argument%s1">; def err_attribute_too_few_arguments : Error< "%0 attribute takes at least %1 argument%s1">; +// OHOS_LOCAL begin +def warn_invalid_optimize_attr_argument : Warning < + "bad option '%1' to attribute %0; " + "attribute ignored">, InGroup; +def warn_invalid_optimize_attr_type : Warning < + "%0 attribute only support string argument; " + "attribute ignored">, InGroup; +// OHOS_LOCAL end def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">; def err_attribute_bad_neon_vector_size : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index ebbd8db313428549fc3350ee5405c8dc842ea118..292c295e5c0b89a5bee952ddc0ff4eafba7f1b44 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -202,6 +202,7 @@ def OpaqueValueExpr : StmtNode; def TypoExpr : StmtNode; def RecoveryExpr : StmtNode; def BuiltinBitCastExpr : StmtNode; +def HMTypeSigExpr : StmtNode; // Microsoft Extensions. def MSPropertyRefExpr : StmtNode; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 47e4c2754dd05865e4a055a17d892090cf839325..bf8e53887c0ff90cbe5ecd45cccf2c161b20cdff 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -434,7 +434,10 @@ KEYWORD(__builtin_LINE , KEYALL) KEYWORD(__builtin_COLUMN , KEYALL) KEYWORD(__builtin_source_location , KEYCXX) -UNARY_EXPR_OR_TYPE_TRAIT(__builtin_get_modifier_bytype, PacModifierByType, KEYALL) // OHOS_LOCAL +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_get_modifier_bytype, PacModifierByType, + KEYALL) // OHOS_LOCAL +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_hm_type_summary, HMTypeSummary, KEYALL) +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_hm_type_signature, HMTypeSignature, KEYALL) // __builtin_types_compatible_p is a GNU C extension that we handle like a C++ // type trait. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8f2800d6f2eaf18096157593406d5a9eb7bb91af..f6c04c9871dddcc5556f8aeb7f7c41e3fb390287 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5854,6 +5854,11 @@ public: bool CheckCaseExpression(Expr *E); + // __builtin_hm_type_signature(type) + ExprResult ActOnHMTypeSig(SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + ParsedType ParsedTy, SourceRange ArgRange); + /// Describes the result of an "if-exists" condition check. enum IfExistsResult { /// The symbol exists. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 58f456486f6def43655bd09aefca2e060968e660..e2d96c3419a64dfd76855c7a363e1ad2e3877304 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1888,6 +1888,7 @@ enum StmtCode { EXPR_CXX_FOLD, // CXXFoldExpr EXPR_CONCEPT_SPECIALIZATION, // ConceptSpecializationExpr EXPR_REQUIRES, // RequiresExpr + EXPR_HM_TYPE_SIG, // A HMTypeSigExpr record. // CUDA EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index ca477e6500c5ec6ab3239d8ca5368a82b23dba33..84d054c461ebdebc37e343e85ef1aefd9fece7cd 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3483,6 +3483,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ConceptSpecializationExprClass: case RequiresExprClass: case SYCLUniqueStableNameExprClass: + case HMTypeSigExprClass: //OHOS_LOCAL // These never have a side-effect. return false; @@ -4852,6 +4853,253 @@ RecoveryExpr *RecoveryExpr::CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs) { return new (Mem) RecoveryExpr(EmptyShell(), NumSubExprs); } +// OHOS_LOCAL begin +HMTypeSigExpr::HMTypeSigExpr(UnaryExprOrTypeTrait ExprKind, + TypeSourceInfo *TInfo, QualType resultTy, + SourceLocation op, SourceLocation rp) + : Expr(HMTypeSigExprClass, resultTy, VK_PRValue, OK_Ordinary), OpLoc(op), + RParenLoc(rp) { + this->DataType = TInfo->getType(); + this->ExprKind = ExprKind; +} + +HMTypeSigExpr::FieldType +HMTypeSigExpr::getFieldTypeEnum(QualType FieldTy) const { + if (FieldTy->isPointerType()) { + return HMTypeSigExpr::POINTER; + } else { + if (const auto *TT = FieldTy->getAs()) { + auto typedefName = TT->getDecl()->getName(); + if (typedefName == "uptr_t" || typedefName == "ptr_t" || + typedefName == "uintptr_t" || + typedefName == "intptr_t") { + return HMTypeSigExpr::POINTER; + } + } + return HMTypeSigExpr::DATA; + } +} + +StringRef HMTypeSigExpr::getBuiltinStr() const { + if (getKind() == UETT_HMTypeSummary) + return "__builtin_hm_type_summary"; + else + return "__builtin_hm_type_signature"; +} + +APValue HMTypeSigExpr::getBuiltinResult(const ASTContext &Ctx, + std::string signature, + unsigned short summary) const { + if (getKind() == UETT_HMTypeSignature) + return MakeStringLiteral(signature, Ctx); + else + return APValue(llvm::APSInt( + llvm::APInt(Ctx.getIntWidth(Ctx.UnsignedShortTy), summary, false))); +} + +APValue HMTypeSigExpr::MakeStringLiteral(StringRef Tmp, + const ASTContext &Ctx) const { + using LValuePathEntry = APValue::LValuePathEntry; + StringLiteral *Res = Ctx.getPredefinedStringLiteralFromCache(Tmp); + // Decay the string to a pointer to the first character. + LValuePathEntry Path[1] = {LValuePathEntry::ArrayIndex(0)}; + return APValue(Res, CharUnits::Zero(), Path, /*OnePastTheEnd=*/false); +} + +APValue HMTypeSigExpr::EvaluateTypeSig(const ASTContext &Ctx) const { + if (!DataType->isRecordType()) { + return getBuiltinResult(Ctx, + getFieldTypeStr(getFieldTypeEnum( + DataType)), + 1 << getFieldTypeEnum(DataType)); + } + RecordDecl *RD = DataType->castAs()->getDecl(); + if (!RD->getDefinition()) { + llvm::errs() << "Only definitions can get signature.\n"; + return getBuiltinResult(Ctx, + getFieldTypeStr(getFieldTypeEnum( + DataType)), + 1 << getFieldTypeEnum(DataType)); + } + uint64_t GranulesPos = 0; + std::vector> GranulesVec; + std::vector vec; + GranulesVec.push_back(vec); + divideGranules(DataType, Ctx, GranulesPos, GranulesVec); + std::string signature; + unsigned summary = 0; + for (auto tmpVec : GranulesVec) { + unsigned GranulesValue = 0; + if (tmpVec.empty()) { + continue; + } + for (auto type : tmpVec) { + GranulesValue = + GranulesValue | type; // Calculate the value of a single particle. + } + signature += std::to_string(GranulesValue); + summary |= (1 << GranulesValue); + } + return getBuiltinResult(Ctx, signature, summary); +} + +void HMTypeSigExpr::divideGranules( + QualType CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (CurType->isRecordType()) { + divideGranulesRecord(CurType->castAs(), Ctx, GranulesPos, vec); + } else if (CurType->isArrayType()) { + divideGranulesArray(Ctx.getAsArrayType(CurType), Ctx, GranulesPos, vec); + } else if (CurType->isVectorType()) { + divideGranulesVector(CurType->castAs(), Ctx, GranulesPos, vec); + } else { + uint64_t fieldSize = Ctx.getTypeSize(CurType); + divideGranulesBase(getFieldTypeEnum(CurType), fieldSize, Ctx, GranulesPos, + vec); + } +} + +void HMTypeSigExpr::divideGranules( + const FieldDecl *Field, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + auto CurType = Field->getType(); + if (Field->isBitField()) { + uint64_t fieldSize = Field->getBitWidthValue(Ctx); + divideGranulesBase(getFieldTypeEnum(CurType), fieldSize, Ctx, GranulesPos, + vec); + return; + } + divideGranules(CurType, Ctx, GranulesPos, vec); +} + +bool HMTypeSigExpr::divideGranulesBase( + FieldType CurType, uint64_t fieldSize, const ASTContext &Ctx, + uint64_t &GranulesPos, std::vector> &vec) const { + if ((GranulesPos + fieldSize) <= GranulesSize) { + vec.back().push_back(CurType); + GranulesPos += fieldSize; + } else { + uint64_t tmpSize = GranulesSize - GranulesPos; + // There are also 128-bit integers, which are added in two parts. + divideGranulesBase(CurType, tmpSize, Ctx, GranulesPos, vec); + fieldSize = fieldSize - tmpSize; + divideGranulesBase(CurType, fieldSize, Ctx, GranulesPos, vec); + return true; + } + if (GranulesPos == GranulesSize) { + std::vector subVec; + vec.push_back(subVec); + GranulesPos = 0; + } + return true; +} + +void HMTypeSigExpr::divideGranulesArray( + const ArrayType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (!CurType) { + return; + } + uint64_t fieldSize = Ctx.getTypeSize(CurType); + auto elemType = CurType->getElementType(); + uint64_t elemSize = Ctx.getTypeSize(elemType); + for (uint64_t elemPos = 0; elemPos < fieldSize; elemPos += elemSize) { + divideGranules(elemType, Ctx, GranulesPos, vec); + } +} + +void HMTypeSigExpr::divideGranulesVector( + const VectorType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (!CurType) { + return; + } + unsigned elemNum = CurType->getNumElements(); + auto elemType = CurType->getElementType(); + for (unsigned i = 0; i < elemNum; i++) { + divideGranules(elemType, Ctx, GranulesPos, vec); + } +} + +void HMTypeSigExpr::divideGranulesUnion( + const RecordType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + RecordDecl *RD = CurType->getDecl(); + uint64_t UnionSize = Ctx.getTypeSize(CurType); + std::vector> GranulesResult; + uint64_t TmpPos = GranulesPos; + for (auto *Field : RD->fields()) { + std::vector> GranulesVec; + std::vector TmpVec; + GranulesVec.push_back(TmpVec); + TmpPos = GranulesPos; + uint64_t FieldSz = Field->isBitField() ? Field->getBitWidthValue(Ctx) + : Ctx.getTypeSize(Field->getType()); + divideGranules(Field, Ctx, TmpPos, GranulesVec); + if (UnionSize > FieldSz) { + uint64_t FieldSize = UnionSize - FieldSz; + divideGranulesBase(PADDING, FieldSize, Ctx, TmpPos, GranulesVec); + } + unsigned i = 0; + unsigned vecSize = GranulesResult.size(); + for (auto tmpVec : GranulesVec) { + if (i < vecSize) { + GranulesResult[i].insert(GranulesResult[i].end(), tmpVec.begin(), + tmpVec.end()); + } else { + GranulesResult.push_back(tmpVec); + } + i++; + } + } + for (unsigned i = 0; i < GranulesResult.size(); i++) { + if (i == 0) { + for (auto type : GranulesResult[i]) { + vec.back().push_back(type); + } + } else { + vec.push_back(GranulesResult[i]); + } + } + GranulesPos = TmpPos; +} + +void HMTypeSigExpr::divideGranulesRecord( + const RecordType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (!CurType) { + return; + } + RecordDecl *RD = CurType->getDecl(); + if (!RD->getDefinition()) { + llvm::errs() << RD->getNameAsString() + << "not defination cannot get signature.\n"; + return; + } + if (RD->isUnion()) { + return divideGranulesUnion(CurType, Ctx, GranulesPos, vec); + } + uint64_t preFieldEnd = 0, curFieldStart = 0; + const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); + for (auto *Field : RD->fields()) { + curFieldStart = Layout.getFieldOffset(Field->getFieldIndex()); + if (curFieldStart > preFieldEnd) { + uint64_t fieldSize = curFieldStart - preFieldEnd; + divideGranulesBase(PADDING, fieldSize, Ctx, GranulesPos, vec); + } + divideGranules(Field, Ctx, GranulesPos, vec); + uint64_t FieldSz = Field->isBitField() ? Field->getBitWidthValue(Ctx) + : Ctx.getTypeSize(Field->getType()); + preFieldEnd = curFieldStart + FieldSz; + } + curFieldStart = Ctx.getTypeSize(CurType); + if (curFieldStart > preFieldEnd) { + uint64_t fieldSize = curFieldStart - preFieldEnd; + divideGranulesBase(PADDING, fieldSize, Ctx, GranulesPos, vec); + } +} +// OHOS_LOCAL end. + void OMPArrayShapingExpr::setDimensions(ArrayRef Dims) { assert( NumDims == Dims.size() && diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 6c122cac2c60b75122da0b904be26e281569a3f8..b5bdca86cf77f784ce68774f0efed783d6cf123b 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -203,6 +203,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::SourceLocExprClass: case Expr::ConceptSpecializationExprClass: case Expr::RequiresExprClass: + case Expr::HMTypeSigExprClass: return Cl::CL_PRValue; case Expr::ConstantExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d22135079fa636dde8244b034b16b13de0c87d72..98f46321943a1c76deff6a49974839c5060dc265 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2026,6 +2026,8 @@ static bool IsGlobalLValue(APValue::LValueBase B) { // constructor can produce a constant expression. We must assume that such // an expression might be a global lvalue. return true; + case Expr::HMTypeSigExprClass: // OHOS_LOCAL + return true; } } @@ -8795,6 +8797,14 @@ public: return true; } + bool VisitHMTypeSigExpr(const HMTypeSigExpr *E) { + if (E->getKind() != UETT_HMTypeSignature) + return false; + APValue LValResult = E->EvaluateTypeSig(Info.Ctx); + Result.setFrom(Info.Ctx, LValResult); + return true; + } + // FIXME: Missing: @protocol, @selector }; } // end anonymous namespace @@ -10985,6 +10995,7 @@ public: bool VisitCastExpr(const CastExpr* E); bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); + bool VisitHMTypeSigExpr(const HMTypeSigExpr *E); bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return Success(E->getValue(), E); @@ -13288,6 +13299,10 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( } return Success(0, E); } + case UETT_HMTypeSummary: + case UETT_HMTypeSignature: { + return false; + } // OHOS_LOCAL End case UETT_OpenMPRequiredSimdAlign: assert(E->isArgumentType()); @@ -13300,6 +13315,14 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( llvm_unreachable("unknown expr/type trait"); } + +bool IntExprEvaluator::VisitHMTypeSigExpr(const HMTypeSigExpr *E) { + if (E->getKind() != UETT_HMTypeSummary) { + return false; + } + APValue LValResult = E->EvaluateTypeSig(Info.Ctx); + return Success(LValResult, E); +} bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { CharUnits Result; @@ -15475,6 +15498,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ArrayTypeTraitExprClass: case Expr::ExpressionTraitExprClass: case Expr::CXXNoexceptExprClass: + case Expr::HMTypeSigExprClass: return NoDiag(); case Expr::CallExprClass: case Expr::CXXOperatorCallExprClass: { diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index b1091945d85f076b841a6bea73e8193344fe6ed9..2341e2c7a36d907b4e8e55eaff751b81592f52da 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4289,6 +4289,7 @@ recurse: case Expr::AtomicExprClass: case Expr::SourceLocExprClass: case Expr::BuiltinBitCastExprClass: + case Expr::HMTypeSigExprClass: { NotPrimaryExpr(); if (!NullOut) { @@ -4692,6 +4693,8 @@ recurse: return; } // OHOS_LOCAL Begin + case UETT_HMTypeSummary: + case UETT_HMTypeSignature: case UETT_PacModifierByType: { return; } diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 625048c69a86427ea4771fb59b8720c68c798d3e..a891ec4fe92861faf08fffdf9e45c6cb6acbf46c 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -2716,6 +2716,10 @@ void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { OS << ")"; } +void StmtPrinter::VisitHMTypeSigExpr(HMTypeSigExpr *Node) { + OS << Node->getBuiltinStr() << "()"; +} + //===----------------------------------------------------------------------===// // Stmt method implementations //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 92a8b18cf68a30bae0ef4ecce839137bf1a50786..35e289bd2da384ce7860d2a6fa21da57bfa7a028 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2215,6 +2215,10 @@ void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) { void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); } +void StmtProfiler::VisitHMTypeSigExpr(const HMTypeSigExpr *E) { + VisitExpr(E); +} + void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) { VisitExpr(S); } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3848f10a6789f95090f406d6f0ff6bec7cf16a84..a334bb616d5345491eb2b68d8129703d1bd19b74 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1780,6 +1780,31 @@ static void AddAttributesFromAssumes(llvm::AttrBuilder &FuncAttrs, llvm::join(Attrs.begin(), Attrs.end(), ",")); } +// OHOS_LOCAL begin +static void AddAttributesFromOptimize(llvm::AttrBuilder &FuncAttrs, + const Decl *Callee) { + if (!Callee) + return; + + const OptimizeAttr *OptAttrObj = Callee->getAttr(); + if (!OptAttrObj) + return; + + for (const auto &OA : OptAttrObj->optAttrs()) { + switch (OA) { + case OptimizeAttr::OmitFramePointer: + FuncAttrs.addAttribute("OPT-omit-frame-pointer"); + break; + case OptimizeAttr::NoOmitFramePointer: + FuncAttrs.addAttribute("OPT-no-omit-frame-pointer"); + break; + default: + llvm_unreachable("invalid enum"); + } + } +} +// OHOS_LOCAL end + bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) { // We can't just discard the return value for a record type with a @@ -1832,6 +1857,13 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, FpKind = "all"; break; } + // OHOS_LOCAL begin + // optimize attr's priority is higher than command line args + if (FuncAttrs.contains("OPT-omit-frame-pointer")) + FpKind = "none"; + if (FuncAttrs.contains("OPT-no-omit-frame-pointer")) + FpKind = "all"; + // OHOS_LOCAL end FuncAttrs.addAttribute("frame-pointer", FpKind); if (CodeGenOpts.LessPreciseFPMAD) @@ -2090,6 +2122,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // Attach assumption attributes to the declaration. If this is a call // site, attach assumptions from the caller to the call as well. AddAttributesFromAssumes(FuncAttrs, TargetDecl); + AddAttributesFromOptimize(FuncAttrs, TargetDecl); // OHOS_LOCAL bool HasOptnone = false; // The NoBuiltinAttr attached to the target FunctionDecl. diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 747bb00dee299edb487a428b75bcb97186adb84f..4456e66bcd1421cfbacab8b655f0a5c5455be973 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -646,7 +646,12 @@ public: return ConstantEmitter(CGF).emitAbstract(SLE->getLocation(), Evaluated, SLE->getType()); } - + Value *VisitHMTypeSigExpr(HMTypeSigExpr *SLE) { + auto &Ctx = CGF.getContext(); + APValue Evaluated = SLE->EvaluateTypeSig(Ctx); + return ConstantEmitter(CGF).emitAbstract(SLE->getBeginLoc(), Evaluated, + SLE->getType()); + } Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); return Visit(DAE->getExpr()); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e9635356e26f267248ced7f1bd5303ee1905bdcd..173437e231b3e8d4d6a9edf3cb7bab0a061abeb9 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2160,6 +2160,21 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, llvm::StringMap FeatureMap; getContext().getFunctionFeatureMap(FeatureMap, GD); + // OHOS_LOCAL begin + auto TargetArch = getContext().getTargetInfo().getTriple().getArch(); + // Enable aarch64 target attribute: general-regs-only + if (TargetArch == llvm::Triple::aarch64 || + TargetArch == llvm::Triple::aarch64_be) { + auto EntryIt = FeatureMap.find("general-regs-only"); + if (EntryIt != FeatureMap.end() && EntryIt->getValue()) { + FeatureMap["neon"] = false; + FeatureMap["crypto"] = false; + FeatureMap["fp-armv8"] = false; + FeatureMap["sve"] = false; + FeatureMap.erase("general-regs-only"); + } + } + // OHOS_LOCAL end // Produce the canonical string for this set of features. for (const llvm::StringMap::value_type &Entry : FeatureMap) Features.push_back((Entry.getValue() ? "+" : "-") + Entry.getKey().str()); diff --git a/clang/lib/Pac/PacDfi.cpp b/clang/lib/Pac/PacDfi.cpp index 2a2e502f4e252d269d2690c5c55197fa251d7a42..d73e16edf8882f40bb048d888fa72a8bb1b53cd8 100644 --- a/clang/lib/Pac/PacDfi.cpp +++ b/clang/lib/Pac/PacDfi.cpp @@ -27,15 +27,80 @@ using namespace clang; std::map RecordDecl2StructName; std::map> PacPtrNameInfos; std::map> PacFieldNameInfos; +std::map> PacFieldExclNameInfos; +std::map> PacFieldSeqlNameInfos; std::map RecordDecl2StructType; + +bool IsBaseTypeNotArrStruct(RecordDecl *TagDecl, FieldDecl *Field, DiagnosticsEngine &Diags) +{ + if (Field->getType()->isConstantArrayType()) { + Diags.Report(Field->getLocation(), diag::warn_unsupported_pac_dfi_type) << "array" + << Field->getAttr()->getSpelling(); + return false; + } + return true; +} + +void AppendFieldDecl(RecordDecl *TagDecl, FieldDecl *TargetField, FieldDecl *NewField) +{ + const RecordDecl::field_iterator TargetFieldIt = std::find(TagDecl->field_begin(), TagDecl->field_end(), TargetField); + if (TargetFieldIt != TagDecl->field_end()) { + llvm::SmallVector Fields; + + for (FieldDecl *TmpFD :TagDecl->fields()) { + Fields.push_back(TmpFD); + } + for (FieldDecl *TmpFD : Fields) { + TagDecl->removeDecl(TmpFD); + } + for (FieldDecl *TmpFD : Fields) { + TagDecl->addDecl(TmpFD); + if (TmpFD == TargetField) { + TagDecl->addDecl(NewField); + } + } + } +} + +void AppendPacFieldDecl(RecordDecl *TagDecl, FieldDecl *Field, ASTContext &Ctx) +{ + auto IntType = Ctx.getBitIntType(true, 64); + FieldDecl *PacFD = FieldDecl::Create(Ctx, TagDecl, SourceLocation(), SourceLocation(), + nullptr, IntType, nullptr, nullptr, true, ICIS_NoInit); + llvm::APInt PacAlign(32, 16); + Field->addAttr(AlignedAttr::CreateImplicit( + Ctx, + true, + IntegerLiteral::Create(Ctx, PacAlign, Ctx.IntTy, + SourceLocation()), + {}, + AttributeCommonInfo::AS_GNU, + AlignedAttr::GNU_aligned)); + AppendFieldDecl(TagDecl, Field, PacFD); +} + +void AppendPacArrayFieldDecl(RecordDecl *TagDecl, FieldDecl *Field, unsigned ArySize, ASTContext &Ctx) +{ + auto Int64Ty = Ctx.getBitIntType(true, 64); + auto Int64ArrayTy = Ctx.getConstantArrayType(Int64Ty, llvm::APInt(64, ArySize), + nullptr, ArrayType::Normal, 0); + FieldDecl *PacArrayFD = FieldDecl::Create(Ctx, TagDecl, SourceLocation(), SourceLocation(), + nullptr, Int64ArrayTy, nullptr, nullptr, true, ICIS_NoInit); + + AppendFieldDecl(TagDecl, Field, PacArrayFD); +} + void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine &Diags) { if (!llvm::PARTS::useDataFieldTag()) { return; } + // find pac_tag attr fields, and insert new fields std::vector PacPtrNames; std::vector PacFieldNames; + std::vector PacFieldExclNames; + std::vector PacFieldSeqlNames; unsigned int ArraySize = 0; for (auto *Field : TagDecl->fields()) { @@ -59,6 +124,19 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine & << Field->getAttr()->getSpelling(); continue; } + if (Field->hasAttr()) { + if (!IsBaseTypeNotArrStruct(TagDecl, Field, Diags)) { + continue; + } + AppendPacFieldDecl(TagDecl, Field, Ctx); + PacFieldExclNames.push_back(Field); + continue; + } + if (Field->hasAttr()) { + AppendPacArrayFieldDecl(TagDecl, Field, Inc, Ctx); + PacFieldSeqlNames.push_back(Field); + continue; + } ArraySize += Inc; PacFieldNames.push_back(Field); } else if (Field->hasAttr()) { @@ -85,6 +163,12 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine & if (!PacPtrNames.empty()) { PacPtrNameInfos.insert(std::make_pair(TagDecl, PacPtrNames)); } + if (!PacFieldExclNames.empty()) { + PacFieldExclNameInfos.insert(std::make_pair(TagDecl, PacFieldExclNames)); + } + if (!PacFieldSeqlNames.empty()) { + PacFieldSeqlNameInfos.insert(std::make_pair(TagDecl, PacFieldSeqlNames)); + } } void PacDfiCreateMetaData(std::map> &fieldInfos, StringRef mdName, @@ -126,6 +210,12 @@ void PacDfiEmitStructFieldsMetadata(llvm::Module &M, CodeGen::CodeGenModule *CGM if (!PacPtrNameInfos.empty()) { PacDfiCreateMetaData(PacPtrNameInfos, "pa_ptr_field_info", M, CGM, func); } + if (!PacFieldExclNameInfos.empty()) { + PacDfiCreateMetaData(PacFieldExclNameInfos, "pa_excl_field_info", M, CGM, func); + } + if (!PacFieldSeqlNameInfos.empty()) { + PacDfiCreateMetaData(PacFieldSeqlNameInfos, "pa_seql_field_info", M, CGM, func); + } } void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry) @@ -137,4 +227,5 @@ void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry) return; } RecordDecl2StructName.insert(std::make_pair(RD, Entry->getName())); -} \ No newline at end of file +} + diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 2b506786df770a095f44bc7f26c75b4d4c8925c0..36f4f1a3412d6925ad3eddc4426ec9d31748304b 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1423,6 +1423,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' case tok::kw___builtin_omp_required_simd_align: case tok::kw___builtin_get_modifier_bytype: // OHOS_LOCAL + case tok::kw___builtin_hm_type_summary: + case tok::kw___builtin_hm_type_signature: if (NotPrimaryExpression) *NotPrimaryExpression = true; AllowSuffix = false; @@ -2286,8 +2288,9 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, tok::kw___builtin_omp_required_simd_align, - tok::kw___builtin_get_modifier_bytype // OHOS_LOCAL - ) && + tok::kw___builtin_get_modifier_bytype, + tok::kw___builtin_hm_type_summary, + tok::kw___builtin_hm_type_signature) && "Not a typeof/sizeof/alignof/vec_step expression!"); ExprResult Operand; @@ -2297,9 +2300,9 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, // If construct allows a form without parenthesis, user may forget to put // pathenthesis around type name. if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, - tok::kw__Alignof, - tok::kw___builtin_get_modifier_bytype // OHOS_LOCAL - )) { + tok::kw__Alignof, tok::kw___builtin_get_modifier_bytype, + tok::kw___builtin_hm_type_summary, + tok::kw___builtin_hm_type_signature)) { if (isTypeIdUnambiguously()) { DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); @@ -2409,7 +2412,9 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, tok::kw___builtin_omp_required_simd_align, - tok::kw___builtin_get_modifier_bytype) && // OHOS_LOCAL + tok::kw___builtin_get_modifier_bytype, + tok::kw___builtin_hm_type_summary, + tok::kw___builtin_hm_type_signature) && "Not a sizeof/alignof/vec_step/get_modifier_bytype expression!"); Token OpTok = Tok; ConsumeToken(); @@ -2489,6 +2494,16 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { else if (OpTok.is(tok::kw___builtin_get_modifier_bytype)) ExprKind = UETT_PacModifierByType; // OHOS_LOCAL End + else if (OpTok.is(tok::kw___builtin_hm_type_summary)) + ExprKind = UETT_HMTypeSummary; + else if (OpTok.is(tok::kw___builtin_hm_type_signature)) + ExprKind = UETT_HMTypeSignature; + + if (isCastExpr && (OpTok.is(tok::kw___builtin_hm_type_summary) || + OpTok.is(tok::kw___builtin_hm_type_signature))) { + return Actions.ActOnHMTypeSig(OpTok.getLocation(), ExprKind, CastTy, + CastRange); + } if (isCastExpr) return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), ExprKind, diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 00120cc54c4b646eb5502729f71deba275a90dde..8a105b988c466bae092ee520252d0a7b35bb93bb 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4794,6 +4794,42 @@ static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(Optnone); } +// OHOS_LOCAL begin +// 'optimize' attribute only accept string argument, just warning if invalid type +static void handleOptimizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!AL.checkAtLeastNumArgs(S, 1)) + return; + + SmallVector OptAttrs; + for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) { + if (AL.isArgIdent(ArgIndex)) { + S.Diag(AL.getLoc(), diag::warn_invalid_optimize_attr_type) << AL; + return; + } + + Expr *ArgExpr = AL.getArgAsExpr(ArgIndex); + SourceLocation Loc = ArgExpr->getBeginLoc(); + const auto *Literal = dyn_cast(ArgExpr->IgnoreParenCasts()); + if (!Literal) { + S.Diag(Loc, diag::warn_invalid_optimize_attr_type) << AL; + return; + } + + StringRef OptAttrStr = Literal->getString(); + OptimizeAttr::OptAttrKind OptAttr; + if (!OptimizeAttr::ConvertStrToOptAttrKind(OptAttrStr, OptAttr)) { + S.Diag(Loc, diag::warn_invalid_optimize_attr_argument) << AL << OptAttrStr; + return; + } + + OptAttrs.push_back(OptAttr); + } + + D->addAttr(::new (S.Context) + OptimizeAttr(S.Context, AL, OptAttrs.data(), OptAttrs.size())); +} +// OHOS_LOCAL end + static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const auto *VD = cast(D); if (VD->hasLocalStorage()) { @@ -8603,6 +8639,11 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_OptimizeNone: handleOptimizeNoneAttr(S, D, AL); break; + // OHOS_LOCAL begin + case ParsedAttr::AT_Optimize: + handleOptimizeAttr(S, D, AL); + break; + // OHOS_LOCAL end case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break; diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index d8344cfd01f951365f63efb7b5b3557299e445ca..2c048a1369bf121924104c6f151a6bd66791499f 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1404,6 +1404,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::SourceLocExprClass: case Expr::ConceptSpecializationExprClass: case Expr::RequiresExprClass: + case Expr::HMTypeSigExprClass: // These expressions can never throw. return CT_Cannot; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 83081bbf0aa0c34e9cc1304c90110d44d89cc565..2533f382ed82f8dd0ff6605af7a33791ef51db2a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -20813,3 +20813,22 @@ ExprResult Sema::CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, return RecoveryExpr::Create(Context, T, Begin, End, SubExprs); } + +// __builtin_hm_type_signature +ExprResult Sema::ActOnHMTypeSig(SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + ParsedType ParsedTy, SourceRange ArgRange) { + QualType resultTy; + TypeSourceInfo *TInfo; + GetTypeFromParser(ParsedTy, &TInfo); + if (ExprKind == UETT_HMTypeSummary) + resultTy = Context.UnsignedShortTy; + else { // UETT_HMTypeSignature + assert(ExprKind == UETT_HMTypeSignature); + QualType ArrTy = Context.getStringLiteralArrayType(Context.CharTy, 0); + resultTy = + Context.getPointerType(ArrTy->getAsArrayTypeUnsafe()->getElementType()); + } + return new (Context) + HMTypeSigExpr(ExprKind, TInfo, resultTy, OpLoc, ArgRange.getEnd()); +} diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a8589191fc919b503a0c76a5804a6706d2471491..2344ac2aeb6d27ba10bf4a117a8750c9c32f29f4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -11770,6 +11770,11 @@ ExprResult TreeTransform::TransformSourceLocExpr(SourceLocExpr *E) { getSema().CurContext); } +template +ExprResult TreeTransform::TransformHMTypeSigExpr(HMTypeSigExpr *E) { + return E; +} + template ExprResult TreeTransform::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index e0ae019bf803e01a92a83e1591fdf9845b6ae455..3f85d0c19a069de5fd9703daa2556c52752d900f 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2191,6 +2191,12 @@ void ASTStmtReader::VisitRecoveryExpr(RecoveryExpr *E) { Child = Record.readSubStmt(); } +void ASTStmtReader::VisitHMTypeSigExpr(HMTypeSigExpr *E) { + VisitExpr(E); + E->setOperatorLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); +} + //===----------------------------------------------------------------------===// // Microsoft Expressions and Statements //===----------------------------------------------------------------------===// @@ -4004,7 +4010,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } - case EXPR_REQUIRES: + case EXPR_REQUIRES: { unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields]; unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1]; S = RequiresExpr::Create(Context, Empty, numLocalParameters, @@ -4012,6 +4018,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } + case EXPR_HM_TYPE_SIG: + S = new (Context) HMTypeSigExpr(Empty); + break; + } + // We hit a STMT_STOP, so we're done with this expression. if (Finished) break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 5e5a86ee01a2baeea224ab5a05c8db1277e83f6a..02542490830f8aca6f4978acd3515bbab3669571 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1273,6 +1273,13 @@ void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) { Code = serialization::EXPR_ATOMIC; } +void ASTStmtWriter::VisitHMTypeSigExpr(HMTypeSigExpr *E) { + VisitExpr(E); + Record.AddSourceLocation(E->getOperatorLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + Code = serialization::EXPR_HM_TYPE_SIG; +} + //===----------------------------------------------------------------------===// // Objective-C Expressions and Statements. //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 19149d0798229a5f4c7e9be6bbbf9ca74d1d15f4..56bd1735b3e0b4255a82d2dde72e07473d9670e6 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1606,6 +1606,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPArrayShapingExprClass: case Stmt::OMPIteratorExprClass: case Stmt::SYCLUniqueStableNameExprClass: + case Stmt::HMTypeSigExprClass: case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; diff --git a/clang/test/CodeGen/attr-optimize.c b/clang/test/CodeGen/attr-optimize.c new file mode 100644 index 0000000000000000000000000000000000000000..46347cef8d8feca311f7d3f771af8dc096a5b658 --- /dev/null +++ b/clang/test/CodeGen/attr-optimize.c @@ -0,0 +1,12 @@ +// OHOS_LOCAL begin +// RUN: %clang_cc1 -S -emit-llvm %s -o - | FileCheck %s + +__attribute__((optimize("omit-frame-pointer"))) void f8(void) {} +// CHECK: @f8{{.*}}[[ATTR_omit_frame_pointer:#[0-9]+]] + +__attribute__((optimize("no-omit-frame-pointer"))) void f9(void) {} +// CHECK: @f9{{.*}}[[ATTR_no_omit_frame_pointer:#[0-9]+]] + +// CHECK: attributes [[ATTR_omit_frame_pointer]] = { {{.*}}OPT-omit-frame-pointer{{.*}}"frame-pointer"="none"{{.*}} } +// CHECK: attributes [[ATTR_no_omit_frame_pointer]] = { {{.*}}OPT-no-omit-frame-pointer{{.*}}"frame-pointer"="all"{{.*}} } +// OHOS_LOCAL end diff --git a/clang/test/CodeGen/attr-target-general-regs-only-aarch64.c b/clang/test/CodeGen/attr-target-general-regs-only-aarch64.c new file mode 100644 index 0000000000000000000000000000000000000000..11306b0a1ae5e45d1cefb88ad49c82c5c4264bdd --- /dev/null +++ b/clang/test/CodeGen/attr-target-general-regs-only-aarch64.c @@ -0,0 +1,11 @@ +// OHOS_LOCAL begin +// Test general-regs-only target attribute on aarch64 + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm %s -o - | FileCheck %s + +// CHECK: define{{.*}} void @f() [[GPR_ATTRS:#[0-9]+]] +void __attribute__((target("general-regs-only"))) f(void) { } + +// CHECK: attributes [[GPR_ATTRS]] = { {{.*}} "target-features"="{{.*}}-crypto{{.*}}-fp-armv8{{.*}}-neon{{.*}}" +// OHOS_LOCAL end diff --git a/clang/test/CodeGen/builtin_type_signature_and_summary.c b/clang/test/CodeGen/builtin_type_signature_and_summary.c new file mode 100644 index 0000000000000000000000000000000000000000..283ac386861b00fed25a1b995e18eb51a12ebc36 --- /dev/null +++ b/clang/test/CodeGen/builtin_type_signature_and_summary.c @@ -0,0 +1,247 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +typedef struct { + unsigned int val; +} StructVal1; +typedef struct { + unsigned int val; +} StructVal2; +typedef struct { + unsigned int val; +} StructVal3; +enum EnumType { + TYPE1 = 0, + TYPE2 = 1, + TYPE3 = 2, +}; +struct StructVal { + union { + StructVal1 uid; + StructVal2 gid; + StructVal3 projid; + }; + enum EnumType type; +}; + +struct Composite { + unsigned int hash; + void *inuse; + void *free; + void *dirty; + void *lock; + void *block; + void *count; + void *val; + struct StructVal id; + unsigned long flags; +}; +typedef struct Composite CompositeS; + +struct Test1 { + unsigned int a; + unsigned int b; +}; + +struct Test2 { + unsigned long a; +}; + +struct Test3 { + unsigned int a; + void *ptr; +}; + +union TestUnion { + void *ptr; + unsigned long data; +}; + +struct Test4 { + unsigned int a; + union TestUnion b; + void *ptr; +}; + +struct TypeWithZeroLengthZrray { + int data[0]; +}; + +struct Test5 { + unsigned int a; + struct Test4 b[10]; + struct TypeWithZeroLengthZrray array; +}; + +struct Test6 { + unsigned a : 1; + unsigned b : 2; + unsigned c : 1; + unsigned d : 1; + unsigned e : 1; + unsigned f : 1; + unsigned g : 4; +}; + +union Test7 { + unsigned a : 1; + unsigned b : 2; + unsigned c : 1; + unsigned d : 1; + unsigned e : 1; + unsigned f : 1; + unsigned g : 4; +}; + +struct Test8 { + float a; + double b; +}; + +struct Test9 { + __int128_t a; + __int128_t b; +}; + +union Test10 { + __int128_t a; + __int128_t b; +}; + +struct Test11 { + unsigned int c; + __int128_t a; + unsigned int d; + __int128_t b; +}; + +struct TestAll { + struct Test1 a; // 2 size 64 + struct Test2 b; // 2 offset 64 size 64 + struct Test3 c; // 21 offset 128 size 128 + union TestUnion d; // 3 offset 256 size 64 + struct Test4 e; // 231 offset 320 size 192 + struct Test5 f; // 2 231*10 512 size 1984 + struct Test6 g; // offset 2496 size 32 + union Test7 h; // gh 和在一起 2 2528 32 + struct Test8 i; // 22 2560 128 + struct Test9 j; // 2222 2688 256 + union Test10 k; // 22 2944 128 + CompositeS l; + struct Test11 m; +} __attribute__((used)); + + +int main(void) +{ + // CHECK: @.str = private unnamed_addr constant [2 x i8] c"2\00", align 1 + // CHECK: @.str.1 = private unnamed_addr constant [3 x i8] c"21\00", align 1 + // CHECK: @.str.2 = private unnamed_addr constant [2 x i8] c"3\00", align 1 + // CHECK: @.str.3 = private unnamed_addr constant [11 x i8] c"2111111122\00", align 1 + // CHECK: @.str.4 = private unnamed_addr constant [4 x i8] c"231\00", align 1 + // CHECK: @.str.5 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 + // CHECK: @.str.6 = private unnamed_addr constant [32 x i8] c"2231231231231231231231231231231\00", align 1 + // CHECK: @.str.7 = private unnamed_addr constant [3 x i8] c"22\00", align 1 + // CHECK: @.str.8 = private unnamed_addr constant [5 x i8] c"2222\00", align 1 + // CHECK: @.str.9 = private unnamed_addr constant [9 x i8] c"20222022\00", align 1 + // CHECK: @.str.10 = private unnamed_addr constant [67 x i8] + // c"222132312231231231231231231231231231231222222222211111112220222022\00", align 1 + + char *sign = __builtin_hm_type_signature(struct Test1); + unsigned long sum = __builtin_hm_type_summary(struct Test1); + // expect 2, 4 + // CHECK: store ptr @.str, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test2); + sum = __builtin_hm_type_summary(struct Test2); + // expect 2, 4 + // CHECK: store ptr @.str, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test3); + sum = __builtin_hm_type_summary(struct Test3); + // expect 21, 6 + // CHECK: store ptr @.str.1, ptr %sign, align 8 + // CHECK: store i64 6, ptr %sum, align 8 + + char *unionSign = __builtin_hm_type_signature(union TestUnion); + unsigned long sumUnion = __builtin_hm_type_summary(union TestUnion); + // expect 3,8 + // CHECK: store ptr @.str.2, ptr %unionSign, align 8 + // CHECK: store i64 8, ptr %sumUnion, align 8 + + char *structValSign = __builtin_hm_type_signature(struct StructVal); + sum = __builtin_hm_type_summary(struct StructVal); + // expect 2,4 + // CHECK: store ptr @.str, ptr %structValSign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(CompositeS); + sum = __builtin_hm_type_summary(CompositeS); + // expect 2111111122,6 + // CHECK: store ptr @.str.3, ptr %sign, align 8 + // CHECK: store i64 6, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test4); + sum = __builtin_hm_type_summary(struct Test4); + // expect 231, 14 + // CHECK: store ptr @.str.4, ptr %sign, align 8 + // CHECK: store i64 14, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct TypeWithZeroLengthZrray); + sum = __builtin_hm_type_summary(struct TypeWithZeroLengthZrray); + // expect , 0 + // CHECK: store ptr @.str.5, ptr %sign, align 8 + // CHECK: store i64 0, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test5); + sum = __builtin_hm_type_summary(struct Test5); + // expect 2231231231231231231231231231231, 14 + // CHECK: store ptr @.str.6, ptr %sign, align 8 + // CHECK: store i64 14, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test6); + sum = __builtin_hm_type_summary(struct Test6); + // expect 2, 4 + // CHECK: store ptr @.str, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(union Test7); + sum = __builtin_hm_type_summary(union Test7); + // expect 2, 4 + // CHECK: store ptr @.str, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test8); + sum = __builtin_hm_type_summary(struct Test8); + // expect 22, 4 + // CHECK: store ptr @.str.7, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test9); + sum = __builtin_hm_type_summary(struct Test9); + + // expect 2222, 4 + // CHECK: store ptr @.str.8, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(union Test10); + sum = __builtin_hm_type_summary(union Test10); + // expect 22, 4 + // CHECK: store ptr @.str.7, ptr %sign, align 8 + // CHECK: store i64 4, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct Test11); + sum = __builtin_hm_type_summary(struct Test11); + // expect 20222022, 5 + // CHECK: store ptr @.str.9, ptr %sign, align 8 + // CHECK: store i64 5, ptr %sum, align 8 + + sign = __builtin_hm_type_signature(struct TestAll); + sum = __builtin_hm_type_summary(struct TestAll); + // expect 222132312231231231231231231231231231231222222222211111112220222022, 15 + // CHECK: store ptr @.str.10, ptr %sign, align 8 + // CHECK: store i64 15, ptr %sum, align 8 + + return 0; +} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 1a5775f4e14bf5cbb83b6276df8a93a234578e63..3008bf5afe6ef0f88b4118b45dbc6d88de2f8727 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -143,12 +143,17 @@ // CHECK-NEXT: ObjCSubclassingRestricted (SubjectMatchRule_objc_interface) // CHECK-NEXT: OpenCLIntelReqdSubGroupSize (SubjectMatchRule_function) // CHECK-NEXT: OpenCLNoSVM (SubjectMatchRule_variable) +// OHOS_LOCAL begin +// CHECK-NEXT: Optimize (SubjectMatchRule_function) +// OHOS_LOCAL end // CHECK-NEXT: OptimizeNone (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: Overloadable (SubjectMatchRule_function) // CHECK-NEXT: Owner (SubjectMatchRule_record_not_is_union) // OHOS_LOCAL begin // CHECK-NEXT: PacDataTag (SubjectMatchRule_field) +// CHECK-NEXT: PacExclTag (SubjectMatchRule_field) // CHECK-NEXT: PacPtrTag (SubjectMatchRule_field) +// CHECK-NEXT: PacSeqlTag (SubjectMatchRule_field) // OHOS_LOCAL end // CHECK-NEXT: ParamTypestate (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: PassObjectSize (SubjectMatchRule_variable_is_parameter) diff --git a/clang/test/Sema/attr-optimize.c b/clang/test/Sema/attr-optimize.c new file mode 100644 index 0000000000000000000000000000000000000000..25ba011b7ce3220113209e222511ead19223136a --- /dev/null +++ b/clang/test/Sema/attr-optimize.c @@ -0,0 +1,22 @@ +// OHOS_LOCAL begin +// RUN: %clang_cc1 -verify -fsyntax-only %s + +__attribute__((optimize())) // expected-error {{'optimize' attribute takes at least 1 argument}} +void f0() {} + +__attribute__((optimize(a))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f1() {} + +int b = 1; +__attribute__((optimize(b))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f2() {} + +__attribute__((optimize("omit-frame-pointer"))) // expected-no-error +void f3() {} + +__attribute__((optimize(1))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f12() {} + +__attribute__((optimize(0))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f13() {} +// OHOS_LOCAL end diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 15294dac0977dfc0449ee492d593555173c03e70..d28ff01796be840702a47b3f19c76a4f70aef9d1 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -335,6 +335,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::ObjCSubscriptRefExprClass: case Stmt::RecoveryExprClass: case Stmt::SYCLUniqueStableNameExprClass: + case Stmt::HMTypeSigExprClass: K = CXCursor_UnexposedExpr; break; diff --git a/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp b/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp index ea8e72be287da8c92ed0ba7a53a583c04d226729..75d806bbec9a39f23a7e5fb75dc26235180a90d9 100644 --- a/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp +++ b/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp @@ -18,6 +18,8 @@ #include "gwp_asan/optional/printf.h" #include "gwp_asan/options.h" +#include "print_backtrace_linux_libc.inc" // OHOS_LOCAL + namespace { size_t Backtrace(uintptr_t *TraceBuffer, size_t Size) { static_assert(sizeof(uintptr_t) == sizeof(void *), "uintptr_t is not void*"); @@ -32,28 +34,6 @@ GWP_ASAN_ALWAYS_INLINE size_t SegvBacktrace(uintptr_t *TraceBuffer, size_t Size, void * /*Context*/) { return Backtrace(TraceBuffer, Size); } - -static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength, - gwp_asan::Printf_t Printf) { - if (TraceLength == 0) { - Printf(" \n\n"); - return; - } - - char **BacktraceSymbols = - backtrace_symbols(reinterpret_cast(Trace), TraceLength); - - for (size_t i = 0; i < TraceLength; ++i) { - if (!BacktraceSymbols) - Printf(" #%zu %p\n", i, Trace[i]); - else - Printf(" #%zu %s\n", i, BacktraceSymbols[i]); - } - - Printf("\n"); - if (BacktraceSymbols) - free(BacktraceSymbols); -} } // anonymous namespace namespace gwp_asan { diff --git a/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp b/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp index 442ba653303ab0219dc34cb34865c535d7aaf416..ad9ceddbb1b317a8b363139a7e9393b561c1db6e 100644 --- a/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp +++ b/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp @@ -6,15 +6,42 @@ // //===----------------------------------------------------------------------===// +#include + +#include "gwp_asan/definitions.h" #include "gwp_asan/optional/backtrace.h" +#include "gwp_asan/optional/printf.h" +#include "gwp_asan/options.h" + +extern "C" char **backtrace_symbols(void *const *trace, size_t len); + +#include "print_backtrace_linux_libc.inc" + +// Consistent with musl +extern "C" GWP_ASAN_WEAK size_t +libc_gwp_asan_unwind_fast(size_t *frame_buf, size_t max_record_stack); + +extern "C" GWP_ASAN_WEAK size_t +libc_gwp_asan_unwind_segv(size_t *frame_buf, size_t max_record_stack, void *signal_context); namespace gwp_asan { namespace backtrace { -// These interfaces are implemented by OHOS musl which is registered with gwp_asan. -options::Backtrace_t getBacktraceFunction() { return nullptr; } -PrintBacktrace_t getPrintBacktraceFunction() { return nullptr; } -SegvBacktrace_t getSegvBacktraceFunction() { return nullptr; } +// These interfaces are implemented by OHOS musl which is registered with +// gwp_asan. +options::Backtrace_t getBacktraceFunction() { + assert(&libc_gwp_asan_unwind_fast && + "libc_gwp_asan_unwind_fast wasn't provided from musl."); + return [](size_t *frame_buf, size_t max_record_stack) { + return libc_gwp_asan_unwind_fast(frame_buf, max_record_stack); + }; +} +PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; } +SegvBacktrace_t getSegvBacktraceFunction() { + assert(&libc_gwp_asan_unwind_segv && + "libc_gwp_asan_unwind_segv wasn't provided from musl."); + return libc_gwp_asan_unwind_segv; +} } // namespace backtrace } // namespace gwp_asan diff --git a/compiler-rt/lib/gwp_asan/optional/print_backtrace_linux_libc.inc b/compiler-rt/lib/gwp_asan/optional/print_backtrace_linux_libc.inc new file mode 100644 index 0000000000000000000000000000000000000000..5a91746e8dc3e734a54d69bff4bcc42f3c61890a --- /dev/null +++ b/compiler-rt/lib/gwp_asan/optional/print_backtrace_linux_libc.inc @@ -0,0 +1,43 @@ +//===-- print_backtrace_linux_libc.inc --------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include + +#include "gwp_asan/definitions.h" +#include "gwp_asan/optional/backtrace.h" +#include "gwp_asan/optional/printf.h" +#include "gwp_asan/options.h" + +namespace { +void PrintBacktrace(uintptr_t *Trace, size_t TraceLength, + gwp_asan::Printf_t Printf) { + if (TraceLength == 0) { + Printf(" \n\n"); + return; + } + + char **BacktraceSymbols = + backtrace_symbols(reinterpret_cast(Trace), TraceLength); + + for (size_t i = 0; i < TraceLength; ++i) { + if (!BacktraceSymbols) + Printf(" #%zu %p\n", i, Trace[i]); + else + Printf(" #%zu %s\n", i, BacktraceSymbols[i]); + } + + Printf("\n"); + if (BacktraceSymbols) + free(BacktraceSymbols); +} +} // anonymous namespace diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp index 451eb2739226b960e97ec1acbdca2473c446be1d..bbf251a90cdd055e1b9e112de62b92ec6803134b 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp +++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp @@ -99,6 +99,10 @@ size_t GuardedPoolAllocator::getPlatformPageSize() { return sysconf(_SC_PAGESIZE); } +#if defined(__OHOS__) + extern "C" GWP_ASAN_WEAK int pthread_atfork_for_gwpasan(void (*)(void), void (*)(void), void (*)(void)); +#endif + void GuardedPoolAllocator::installAtFork() { auto Disable = []() { if (auto *S = getSingleton()) @@ -109,6 +113,8 @@ void GuardedPoolAllocator::installAtFork() { S->enable(); }; #if defined(__OHOS__) + Check(pthread_atfork_for_gwpasan, + "No implement for pthread_atfork_for_gwpasan"); // We need to run the gwpasan handler to unlock first after the fork, // otherwise other handlers may call gwpasan malloc to cause a deadlock. // This interface will let the gwpasan handler to be executed first after the fork. diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h index 475b176ccd4742ac7293121db2201f7e1fd2fca5..347fadb99632dfcaa0f4fa333fdb994c82561e5d 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h +++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h @@ -48,7 +48,7 @@ static_assert(sizeof(ThreadLocalPackedVariables) == sizeof(uint64_t), #if defined(__OHOS__) // Musl doesn't support libc using TLS variables now, // so musl puts gwp_asan tls on the pthread, this interface can return the corresponding address. -extern "C" void* get_platform_gwp_asan_tls_slot(); +extern "C" GWP_ASAN_WEAK void *get_platform_gwp_asan_tls_slot(); namespace gwp_asan { inline ThreadLocalPackedVariables *getThreadLocals() { return reinterpret_cast(get_platform_gwp_asan_tls_slot()); diff --git a/compiler-rt/lib/hwasan/CMakeLists.txt b/compiler-rt/lib/hwasan/CMakeLists.txt index 9082f60058ee7a2a6bda477298ff102b0a0dbb96..a9f6006ac05cc8d323e443759401a25ddce5de0e 100644 --- a/compiler-rt/lib/hwasan/CMakeLists.txt +++ b/compiler-rt/lib/hwasan/CMakeLists.txt @@ -14,6 +14,7 @@ set(HWASAN_RTL_SOURCES hwasan_linux.cpp hwasan_memintrinsics.cpp hwasan_poisoning.cpp + hwasan_quarantine.cpp # OHOS_LOCAL hwasan_report.cpp hwasan_setjmp_aarch64.S hwasan_setjmp_x86_64.S @@ -42,6 +43,7 @@ set(HWASAN_RTL_HEADERS hwasan_malloc_bisect.h hwasan_mapping.h hwasan_poisoning.h + hwasan_quarantine.h # OHOS_LOCAL hwasan_report.h hwasan_thread.h hwasan_thread_list.h diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp index 842455150c7b3362f3940e14e10f69b544c75e4f..5f34e021356aff9572dc2b65aeb6f4ad98956bbb 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -20,6 +20,7 @@ #include "hwasan_mapping.h" #include "hwasan_malloc_bisect.h" #include "hwasan_thread.h" +#include "hwasan_thread_list.h" // OHOS_LOCAL #include "hwasan_report.h" namespace __hwasan { @@ -53,6 +54,14 @@ static uptr AlignRight(uptr addr, uptr requested_size) { return addr + kShadowAlignment - tail_size; } +// OHOS_LOCAL begin +int HwasanChunkView::AllocatedByThread() const { + if (metadata_) + return metadata_->thread_id; + return -1; +} +// OHOS_LOCAL end + uptr HwasanChunkView::Beg() const { if (metadata_ && metadata_->right_aligned) return AlignRight(block_, metadata_->get_requested_size()); @@ -80,6 +89,14 @@ void GetAllocatorStats(AllocatorStatCounters s) { allocator.GetStats(s); } +// OHOS_LOCAL begin +void SimpleThreadDeallocate(void *ptr, AllocatorCache *cache) { + CHECK(ptr); + CHECK(cache); + allocator.Deallocate(cache, ptr); +} +// OHOS_LOCAL end + uptr GetAliasRegionStart() { #if defined(HWASAN_ALIASING_MODE) constexpr uptr kAliasRegionOffset = 1ULL << (kTaggableRegionCheckShift - 1); @@ -160,6 +177,12 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, meta->set_requested_size(orig_size); meta->alloc_context_id = StackDepotPut(*stack); meta->right_aligned = false; + // OHOS_LOCAL begin + if (t) + meta->thread_id = t->tid(); + else + meta->thread_id = -1; + // OHOS_LOCAL end if (zeroise) { internal_memset(allocated, 0, size); } else if (flags()->max_malloc_fill_size > 0) { @@ -295,16 +318,43 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { TagMemoryAligned(reinterpret_cast(aligned_ptr), TaggedSize(orig_size), tag); } + +// OHOS_LOCAL begin + int aid = meta->thread_id; if (t) { - allocator.Deallocate(t->allocator_cache(), aligned_ptr); - if (auto *ha = t->heap_allocations()) - ha->push({reinterpret_cast(tagged_ptr), alloc_context_id, - free_context_id, static_cast(orig_size)}); + if (!t->TryPutInQuarantineWithDealloc(reinterpret_cast(aligned_ptr), + TaggedSize(orig_size), + alloc_context_id, free_context_id)) { + allocator.Deallocate(t->allocator_cache(), aligned_ptr); + } + if (t->AllowTracingHeapAllocation()) { + if (auto *ha = t->heap_allocations()) { + if ((flags()->heap_record_max == 0 || + orig_size <= flags()->heap_record_max) && + (flags()->heap_record_min == 0 || + orig_size >= flags()->heap_record_min)) { + ha->push({reinterpret_cast(tagged_ptr), alloc_context_id, + free_context_id, static_cast(orig_size), aid, t->tid()}); + t->inc_record(); + } + } + } } else { SpinMutexLock l(&fallback_mutex); AllocatorCache *cache = &fallback_allocator_cache; + if (hwasanThreadList().AllowTracingHeapAllocation()) { + if ((flags()->heap_record_max == 0 || + orig_size <= flags()->heap_record_max) && + (flags()->heap_record_min == 0 || + orig_size >= flags()->heap_record_min)) { + hwasanThreadList().RecordFallBack( + {reinterpret_cast(tagged_ptr), alloc_context_id, + free_context_id, static_cast(orig_size), aid, 0}); + } + } allocator.Deallocate(cache, aligned_ptr); } +// OHOS_LOCAL end } static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old, diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h index 35c3d6b4bf434148a9a21c1fac928fd94144156c..28f4f74bdb937d80da9f134d156d0a36c60027f6 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.h +++ b/compiler-rt/lib/hwasan/hwasan_allocator.h @@ -35,6 +35,7 @@ struct Metadata { u32 requested_size_high : 31; u32 right_aligned : 1; u32 alloc_context_id; + int thread_id; // OHOS_LOCAL u64 get_requested_size() { return (static_cast(requested_size_high) << 32) + requested_size_low; } @@ -88,6 +89,7 @@ class HwasanChunkView { uptr ActualSize() const; // Size allocated by the allocator. u32 GetAllocStackId() const; bool FromSmallHeap() const; + int AllocatedByThread() const; // OHOS_LOCAL private: uptr block_; Metadata *const metadata_; @@ -104,12 +106,16 @@ struct HeapAllocationRecord { u32 alloc_context_id; u32 free_context_id; u32 requested_size; + int alloc_thread; // OHOS_LOCAL + int free_thread; // OHOS_LOCAL }; typedef RingBuffer HeapAllocationsRingBuffer; void GetAllocatorStats(AllocatorStatCounters s); +void SimpleThreadDeallocate(void *ptr, AllocatorCache *cache); // OHOS_LOCAL + inline bool InTaggableRegion(uptr addr) { #if defined(HWASAN_ALIASING_MODE) // Aliases are mapped next to shadow so that the upper bits match the shadow diff --git a/compiler-rt/lib/hwasan/hwasan_flags.inc b/compiler-rt/lib/hwasan/hwasan_flags.inc index 18ea47f981bec9538c54130c09a4bfe2ec31305a..15f399a0a7f01ba6d436e84a94f25c2c0634cdd8 100644 --- a/compiler-rt/lib/hwasan/hwasan_flags.inc +++ b/compiler-rt/lib/hwasan/hwasan_flags.inc @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// #ifndef HWASAN_FLAG -# error "Define HWASAN_FLAG prior to including this file!" +# error "Define HWASAN_FLAG prior to including this file!" #endif // HWASAN_FLAG(Type, Name, DefaultValue, Description) @@ -38,21 +38,27 @@ HWASAN_FLAG( "bytes that will be filled with malloc_fill_byte on malloc.") HWASAN_FLAG(bool, free_checks_tail_magic, 1, - "If set, free() will check the magic values " - "to the right of the allocated object " - "if the allocation size is not a divident of the granule size") + "If set, free() will check the magic values " + "to the right of the allocated object " + "if the allocation size is not a divident of the granule size") HWASAN_FLAG( int, max_free_fill_size, 0, "HWASan allocator flag. max_free_fill_size is the maximal amount of " "bytes that will be filled with free_fill_byte during free.") HWASAN_FLAG(int, malloc_fill_byte, 0xbe, - "Value used to fill the newly allocated memory.") -HWASAN_FLAG(int, free_fill_byte, 0x55, - "Value used to fill deallocated memory.") + "Value used to fill the newly allocated memory.") +HWASAN_FLAG(int, free_fill_byte, 0x55, "Value used to fill deallocated memory.") HWASAN_FLAG(int, heap_history_size, 1023, - "The number of heap (de)allocations remembered per thread. " - "Affects the quality of heap-related reports, but not the ability " - "to find bugs.") + "The number of heap (de)allocations remembered per thread. " + "Affects the quality of heap-related reports, but not the ability " + "to find bugs.") +// OHOS_LOCAL begin +HWASAN_FLAG( + int, heap_history_size_main_thread, 102300, + "The number of heap (de)allocations remembered for the main thread. " + "Affects the quality of heap-related reports, but not the ability " + "to find bugs.") +// OHOS_LOCAL end HWASAN_FLAG(bool, export_memory_stats, true, "Export up-to-date memory stats through /proc") HWASAN_FLAG(int, stack_history_size, 1024, @@ -73,7 +79,6 @@ HWASAN_FLAG(bool, malloc_bisect_dump, false, "Print all allocations within [malloc_bisect_left, " "malloc_bisect_right] range ") - // Exit if we fail to enable the AArch64 kernel ABI relaxation which allows // tagged pointers in syscalls. This is the default, but being able to disable // that behaviour is useful for running the testsuite on more platforms (the @@ -81,3 +86,42 @@ HWASAN_FLAG(bool, malloc_bisect_dump, false, // are untagged before the call. HWASAN_FLAG(bool, fail_without_syscall_abi, true, "Exit if fail to request relaxed syscall ABI.") + +// OHOS_LOCAL begin +HWASAN_FLAG( + bool, print_uaf_stacks_with_same_tag, true, + "Control the output content of use-after-free, deciding whether to print " + "all stack traces of matched allocations with the same tag restriction.") + +// Heap allocation information for freed threads +HWASAN_FLAG(uptr, freed_threads_history_size, 100, + "The number of freed threads can be recorded.") +HWASAN_FLAG(bool, verbose_freed_threads, false, + "Print the heap allocation information of freed threads.") + +// Limits the size of the heap memory allocated to be recorded in order to +// reduce the data. As a result, information may be missing. By default, the +// minimum/maximum threshold is not set. +HWASAN_FLAG(int, heap_record_min, 0, + "Only recording the heap memory allocation information that is >= " + "heap_record_min.") +HWASAN_FLAG(int, heap_record_max, 0, + "Only recording the heap memory allocation information that is <= " + "heap_record_max.") + +HWASAN_FLAG(int, memory_around_register_size, 128, + "When reporting, the memory content of the address in register " + "±memory_around_register_size is printed.") + +// Set the quarantine area for freed heap, which is used to detect UAF-Write and +// Overflow-Write. Provide the detection capability for dynamic libraries +// compiled without hwasan option. +HWASAN_FLAG(int, heap_quarantine_thread_max_count, 128, + "Set the maximum count for heap quarantine per thread.") +HWASAN_FLAG(int, heap_quarantine_min, 0, + "The freed heap size should be larger than the minimum size before " + "it is placed into the heap quarantine.") +HWASAN_FLAG(int, heap_quarantine_max, 0, + "The freed heap size should be smaller than the maximum size before " + "it is placed into the heap quarantine.") +// OHOS_LOCAL end \ No newline at end of file diff --git a/compiler-rt/lib/hwasan/hwasan_quarantine.cpp b/compiler-rt/lib/hwasan/hwasan_quarantine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad4488670d0a07a94c9361678cf8a5523fb08388 --- /dev/null +++ b/compiler-rt/lib/hwasan/hwasan_quarantine.cpp @@ -0,0 +1,117 @@ +//===-- hwasan_quarantine.cpp -----------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file is a part of HWAddressSanitizer. Provide allocation quarantine +/// ability. +/// +//===----------------------------------------------------------------------===// +#include "hwasan_quarantine.h" + +#include "hwasan_allocator.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_stackdepot.h" +namespace __hwasan { + +void HeapQuarantineController::ClearHeapQuarantine(AllocatorCache *cache) { + CHECK(cache); + if (heap_quarantine_list_) { + DeallocateWithHeapQuarantcheck(heap_quarantine_tail_, cache); + size_t sz = RoundUpTo( + flags()->heap_quarantine_thread_max_count * sizeof(HeapQuarantine), + GetPageSizeCached()); + UnmapOrDie(heap_quarantine_list_, sz); + heap_quarantine_tail_ = 0; + heap_quarantine_list_ = nullptr; + } + heap_quarantine_list_ = nullptr; +} + +bool HeapQuarantineController::TryPutInQuarantineWithDealloc( + uptr ptr, size_t s, u32 aid, u32 fid, AllocatorCache *cache) { + if (IsInPrintf()) { + return false; + } + if ((flags()->heap_quarantine_max > 0) && + (flags()->heap_quarantine_max > s && flags()->heap_quarantine_min <= s)) { + if (UNLIKELY(flags()->heap_quarantine_thread_max_count == 0)) { + return false; + } + if (UNLIKELY(heap_quarantine_list_ == nullptr)) { + size_t sz = RoundUpTo( + flags()->heap_quarantine_thread_max_count * sizeof(HeapQuarantine), + GetPageSizeCached()); + heap_quarantine_list_ = reinterpret_cast( + MmapOrDie(sz, "HeapQuarantine", 0)); + if (UNLIKELY(heap_quarantine_list_ == nullptr)) { + return false; + } + } + PutInQuarantineWithDealloc(ptr, s, aid, fid, cache); + return true; + } + return false; +} + +void HeapQuarantineController::PutInQuarantineWithDealloc( + uptr ptr, size_t s, u32 aid, u32 fid, AllocatorCache *cache) { + if (UNLIKELY(heap_quarantine_tail_ >= + flags()->heap_quarantine_thread_max_count)) { + // free 1/3 heap_quarantine_list + u32 free_count = heap_quarantine_tail_ / 3; + u32 left_count = heap_quarantine_tail_ - free_count; + DeallocateWithHeapQuarantcheck(free_count, cache); + internal_memcpy( + (char *)heap_quarantine_list_, + (char *)heap_quarantine_list_ + free_count * sizeof(HeapQuarantine), + left_count * sizeof(HeapQuarantine)); + internal_memset( + (char *)heap_quarantine_list_ + left_count * sizeof(HeapQuarantine), 0, + free_count * sizeof(HeapQuarantine)); + heap_quarantine_tail_ -= free_count; + } + + heap_quarantine_list_[heap_quarantine_tail_].ptr = ptr; + heap_quarantine_list_[heap_quarantine_tail_].s = s; + heap_quarantine_list_[heap_quarantine_tail_].alloc_context_id = aid; + heap_quarantine_list_[heap_quarantine_tail_].free_context_id = fid; + heap_quarantine_tail_++; + return; +} + +void HeapQuarantineController::DeallocateWithHeapQuarantcheck( + u32 free_count, AllocatorCache *cache) { + static u64 magic; + internal_memset(&magic, flags()->free_fill_byte, sizeof(magic)); + for (u32 i = 0; i < free_count; i++) { + u64 *ptrBeg = reinterpret_cast(heap_quarantine_list_[i].ptr); + if (heap_quarantine_list_[i].s > sizeof(u64)) { + if (flags()->max_free_fill_size > 0) { + uptr fill_size = + Min(heap_quarantine_list_[i].s, (uptr)flags()->max_free_fill_size); + for (size_t j = 0; j < (fill_size - 1) / sizeof(u64); j++) { + if (ptrBeg[j] != magic) { + Printf( + "ptrBeg was re-written after free %p[%zu], %p " + "%016llx:%016llx, freed by:\n", + ptrBeg, j, &ptrBeg[j], ptrBeg[j], magic); + StackDepotGet(heap_quarantine_list_[i].free_context_id).Print(); + Printf("allocated by:\n"); + StackDepotGet(heap_quarantine_list_[i].alloc_context_id).Print(); + break; + } + } + } + } + SimpleThreadDeallocate((void *)ptrBeg, cache); + } +} + +} // namespace __hwasan \ No newline at end of file diff --git a/compiler-rt/lib/hwasan/hwasan_quarantine.h b/compiler-rt/lib/hwasan/hwasan_quarantine.h new file mode 100644 index 0000000000000000000000000000000000000000..1c4c86a26168a51a0f504169c96dc075cf85153e --- /dev/null +++ b/compiler-rt/lib/hwasan/hwasan_quarantine.h @@ -0,0 +1,49 @@ +//===-- hwasan_quarantine.cpp -----------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file is a part of HWAddressSanitizer. Provide allocation quarantine +/// ability header. +/// +//===----------------------------------------------------------------------===// +#ifndef HWASAN_QUARANTINE_H +#define HWASAN_QUARANTINE_H +#include "hwasan_allocator.h" +namespace __hwasan { +struct HeapQuarantine { + uptr ptr; + size_t s; + u32 alloc_context_id; + u32 free_context_id; +}; +// provide heap quarant for per thread, no data race. +class HeapQuarantineController { + private: + u32 heap_quarantine_tail_; + HeapQuarantine *heap_quarantine_list_; + void PutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, u32 fid, + AllocatorCache *cache); + void DeallocateWithHeapQuarantcheck(u32 free_count, AllocatorCache *cache); + + public: + void Init() { + heap_quarantine_tail_ = 0; + heap_quarantine_list_ = nullptr; + } + + void ClearHeapQuarantine(AllocatorCache *cache); + + bool TryPutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, u32 fid, + AllocatorCache *cache); +}; + +} // namespace __hwasan + +#endif // HWASAN_QUARANTINE_H \ No newline at end of file diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp index a59d5fef9791c2f0f2e71d80a583b5f71876733b..051c68ee2e846f5f37347652cf9321ba5ff0417b 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -139,45 +139,6 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { const char *Thread() { return Green(); } }; -static bool FindHeapAllocation(HeapAllocationsRingBuffer *rb, uptr tagged_addr, - HeapAllocationRecord *har, uptr *ring_index, - uptr *num_matching_addrs, - uptr *num_matching_addrs_4b) { - if (!rb) return false; - - *num_matching_addrs = 0; - *num_matching_addrs_4b = 0; - for (uptr i = 0, size = rb->size(); i < size; i++) { - auto h = (*rb)[i]; - if (h.tagged_addr <= tagged_addr && - h.tagged_addr + h.requested_size > tagged_addr) { - *har = h; - *ring_index = i; - return true; - } - - // Measure the number of heap ring buffer entries that would have matched - // if we had only one entry per address (e.g. if the ring buffer data was - // stored at the address itself). This will help us tune the allocator - // implementation for MTE. - if (UntagAddr(h.tagged_addr) <= UntagAddr(tagged_addr) && - UntagAddr(h.tagged_addr) + h.requested_size > UntagAddr(tagged_addr)) { - ++*num_matching_addrs; - } - - // Measure the number of heap ring buffer entries that would have matched - // if we only had 4 tag bits, which is the case for MTE. - auto untag_4b = [](uptr p) { - return p & ((1ULL << 60) - 1); - }; - if (untag_4b(h.tagged_addr) <= untag_4b(tagged_addr) && - untag_4b(h.tagged_addr) + h.requested_size > untag_4b(tagged_addr)) { - ++*num_matching_addrs_4b; - } - } - return false; -} - static void PrintStackAllocations(StackAllocationsRingBuffer *sa, tag_t addr_tag, uptr untagged_addr) { uptr frames = Min((uptr)flags()->stack_history_size, sa->size()); @@ -386,13 +347,22 @@ void PrintAddressDescription( if (uptr beg = chunk.Beg()) { uptr size = chunk.ActualSize(); Printf("%s[%p,%p) is a %s %s heap chunk; " - "size: %zd offset: %zd\n%s", + "size: %zd offset: %zd, Allocated By %u\n%s", // OHOS_LOCAL d.Location(), beg, beg + size, chunk.FromSmallHeap() ? "small" : "large", chunk.IsAllocated() ? "allocated" : "unallocated", size, untagged_addr - beg, + chunk.AllocatedByThread(), // OHOS_LOCAL d.Default()); +// OHOS_LOCAL begin + if (chunk.IsAllocated() && chunk.GetAllocStackId()) { + Printf("%s", d.Allocation()); + Printf("Currently allocated here:\n"); + Printf("%s", d.Default()); + GetStackTraceFromId(chunk.GetAllocStackId()).Print(); + } +// OHOS_LOCAL end } tag_t addr_tag = GetTagFromPointer(tagged_addr); @@ -408,8 +378,8 @@ void PrintAddressDescription( Printf("%s", d.Error()); Printf("\nCause: stack tag-mismatch\n"); Printf("%s", d.Location()); - Printf("Address %p is located in stack of thread T%zd\n", untagged_addr, - t->unique_id()); + Printf("Address %p is located in stack of thread %d\n", untagged_addr, + t->tid()); // OHOS_LOCAL Printf("%s", d.Default()); t->Announce(); @@ -447,53 +417,120 @@ void PrintAddressDescription( if (!on_stack && candidate && candidate_distance <= kCloseCandidateDistance) { ShowHeapOrGlobalCandidate(untagged_addr, candidate, left, right); + candidate = nullptr; // OHOS_LOCAL num_descriptions_printed++; } - hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { - // Scan all threads' ring buffers to find if it's a heap-use-after-free. - HeapAllocationRecord har; - uptr ring_index, num_matching_addrs, num_matching_addrs_4b; - if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har, - &ring_index, &num_matching_addrs, - &num_matching_addrs_4b)) { - Printf("%s", d.Error()); - Printf("\nCause: use-after-free\n"); - Printf("%s", d.Location()); - Printf("%p is located %zd bytes inside of %zd-byte region [%p,%p)\n", - untagged_addr, untagged_addr - UntagAddr(har.tagged_addr), - har.requested_size, UntagAddr(har.tagged_addr), - UntagAddr(har.tagged_addr) + har.requested_size); - Printf("%s", d.Allocation()); - Printf("freed by thread T%zd here:\n", t->unique_id()); - Printf("%s", d.Default()); - GetStackTraceFromId(har.free_context_id).Print(); - - Printf("%s", d.Allocation()); - Printf("previously allocated here:\n", t); - Printf("%s", d.Default()); - GetStackTraceFromId(har.alloc_context_id).Print(); +// OHOS_LOCAL begin + auto PrintUAF = [&](Thread *t, uptr ring_index, HeapAllocationRecord &har) { + uptr ha_untagged_addr = UntagAddr(har.tagged_addr); + Printf("%s", d.Error()); + Printf("\nPotential Cause: use-after-free\n"); + Printf("%s", d.Location()); + Printf( + "%p (rb[%d] tags:%02x) is located %zd bytes inside of %zd-byte region " + "[%p,%p)\n", + untagged_addr, ring_index, GetTagFromPointer(har.tagged_addr), + untagged_addr - ha_untagged_addr, har.requested_size, ha_untagged_addr, + ha_untagged_addr + har.requested_size); + Printf("%s", d.Allocation()); + Printf("freed by thread %d here:\n", t->tid()); + Printf("%s", d.Default()); + GetStackTraceFromId(har.free_context_id).Print(); - // Print a developer note: the index of this heap object - // in the thread's deallocation ring buffer. - Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", ring_index + 1, - flags()->heap_history_size); - Printf("hwasan_dev_note_num_matching_addrs: %zd\n", num_matching_addrs); - Printf("hwasan_dev_note_num_matching_addrs_4b: %zd\n", - num_matching_addrs_4b); + Printf("%s", d.Allocation()); + Printf("previously allocated by thread %d here:\n", har.alloc_thread); + Printf("%s", d.Default()); + GetStackTraceFromId(har.alloc_context_id).Print(); - t->Announce(); - num_descriptions_printed++; + Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", ring_index + 1, + t->IsMainThread() ? flags()->heap_history_size_main_thread + : flags()->heap_history_size); + t->Announce(); + num_descriptions_printed++; + }; + u64 record_searched = 0; + u64 record_matched = 0; + hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { + // Scan all threads' ring buffers to find if it's a heap-use-after-free. + auto *rb = t->heap_allocations(); + if (!rb) + return; + t->DisableTracingHeapAllocation(); + for (uptr i = 0, size = rb->realsize(); i < size; i++) { + auto h = (*rb)[i]; + record_searched++; + if (flags()->print_uaf_stacks_with_same_tag) { + if (h.tagged_addr <= tagged_addr && + h.tagged_addr + h.requested_size > tagged_addr) { + record_matched++; + PrintUAF(t, i, h); + } + } else { + uptr ha_untagged_addr = UntagAddr(h.tagged_addr); + if (ha_untagged_addr <= untagged_addr && + ha_untagged_addr + h.requested_size > untagged_addr) { + record_matched++; + PrintUAF(t, i, h); + } + } } + t->EnableTracingHeapAllocation(); }); - if (candidate && num_descriptions_printed == 0) { + auto PrintUAFinFreedThread = [&](HeapAllocationRecord &har) { + uptr ha_untagged_addr = UntagAddr(har.tagged_addr); + Printf( + "%p (Previously freed thread ptr tags: %02x) is located %zd " + "bytes inside of %zd-byte region [%p,%p)\n", + untagged_addr, GetTagFromPointer(har.tagged_addr), + untagged_addr - ha_untagged_addr, har.requested_size, ha_untagged_addr, + ha_untagged_addr + har.requested_size); + Printf("freed by thread %d here:\n", har.free_thread); + GetStackTraceFromId(har.free_context_id).Print(); + Printf("previously allocated by thread %d here:\n", har.alloc_thread); + GetStackTraceFromId(har.alloc_context_id).Print(); + num_descriptions_printed++; + }; + hwasanThreadList().VisitAllFreedRingBuffer( + [&](HeapAllocationsRingBuffer *rb) { + for (uptr i = 0, size = rb->realsize(); i < size; i++) { + auto har = (*rb)[i]; + record_searched++; + if (flags()->print_uaf_stacks_with_same_tag) { + if (har.tagged_addr <= tagged_addr && + har.tagged_addr + har.requested_size > tagged_addr) { + record_matched++; + PrintUAFinFreedThread(har); + } + } else { + if (UntagAddr(har.tagged_addr) <= untagged_addr && + UntagAddr(har.tagged_addr) + har.requested_size > + untagged_addr) { + record_matched++; + PrintUAFinFreedThread(har); + } + } + } + }); + Printf("Searched %lu records, find %lu with same addr %p\n\n", + record_searched, record_matched, untagged_addr); + if (!on_stack && candidate) { ShowHeapOrGlobalCandidate(untagged_addr, candidate, left, right); num_descriptions_printed++; } // Print the remaining threads, as an extra information, 1 line per thread. hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { t->Announce(); }); + hwasanThreadList().PrintFreedRingBufferSummary(); + if (flags()->verbose_freed_threads) { + u32 freed_idx = 0; + hwasanThreadList().VisitAllFreedRingBuffer( + [&](HeapAllocationsRingBuffer *rb) { + Printf("RB %u: (%zd/%zu)\n", freed_idx++, rb->realsize(), rb->size()); + }); + } +// OHOS_LOCAL end if (!num_descriptions_printed) // We exhausted our possibilities. Bail out. @@ -583,8 +620,10 @@ void ReportInvalidFree(StackTrace *stack, uptr tagged_addr) { const char *bug_type = "invalid-free"; const Thread *thread = GetCurrentThread(); if (thread) { - Report("ERROR: %s: %s on address %p at pc %p on thread T%zd\n", - SanitizerToolName, bug_type, untagged_addr, pc, thread->unique_id()); +// OHOS_LOCAL begin + Report("ERROR: %s: %s on address %p at pc %p on thread %d\n", + SanitizerToolName, bug_type, untagged_addr, pc, thread->tid()); +// OHOS_LOCAL end } else { Report("ERROR: %s: %s on address %p at pc %p on unknown thread\n", SanitizerToolName, bug_type, untagged_addr, pc); @@ -719,14 +758,18 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size, offset += mem_tag - in_granule_offset; } } +// OHOS_LOCAL begin Printf( - "%s of size %zu at %p tags: %02x/%02x(%02x) (ptr/mem) in thread T%zd\n", + "%s of size %zu at %p tags: %02x/%02x(%02x) (ptr/mem) in thread %d\n", is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag, - mem_tag, short_tag, t->unique_id()); + mem_tag, short_tag, t->tid()); +// OHOS_LOCAL end } else { - Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread T%zd\n", +// OHOS_LOCAL begin + Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread %d\n", is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag, - mem_tag, t->unique_id()); + mem_tag, t->tid()); +// OHOS_LOCAL end } if (offset != 0) Printf("Invalid access starting at offset %zu\n", offset); @@ -740,12 +783,60 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size, PrintTagsAroundAddr(tag_ptr); - if (registers_frame) + if (registers_frame) { ReportRegisters(registers_frame, pc); + ReportMemoryNearRegisters(registers_frame, pc); // OHOS_LOCAL + } ReportErrorSummary(bug_type, stack); } +// OHOS_LOCAL begin +void PrintMemoryAroundAddress(MemoryMappingLayout &proc_maps, int reg_num, + uptr addr, uptr len, bool is_pc) { + const sptr kBufSize = 4095; + char *filename = (char *)MmapOrDie(kBufSize, __func__); + MemoryMappedSegment segment(filename, kBufSize); + while (proc_maps.Next(&segment)) { + if (segment.start <= addr && addr < segment.end && segment.IsReadable()) { + if (!is_pc) { + if (reg_num < 31) + Printf("x%d(%s):\n", reg_num, segment.filename); + else + Printf("sp(%s):\n", segment.filename); + } else { + Printf("pc(%s):\n", segment.filename); + } + uptr beg = RoundDownTo(addr - (addr < len ? addr : len), 8); + if (segment.start > beg) + beg = segment.start; + uptr end = RoundUpTo(addr + len, 8); + if (segment.end < end) + end = segment.end; + for (uptr pos = beg; pos < end; pos += 8) { + if (pos <= addr && addr < pos + 8) + Printf("==>\t\t%p %016llx\n", pos, *(uptr *)(pos)); + else + Printf("\t\t%p %016llx\n", pos, *(uptr *)(pos)); + } + break; + } + } +} + +void ReportMemoryNearRegisters(uptr *frame, uptr pc) { + Printf("Memory near registers:\n"); + MemoryMappingLayout proc_maps(/*cache_enabled*/ true); + for (int i = 0; i <= 31; ++i) { + PrintMemoryAroundAddress(proc_maps, i, UntagAddr(frame[i]), + flags()->memory_around_register_size); + proc_maps.Reset(); + } + PrintMemoryAroundAddress(proc_maps, -1, pc, + flags()->memory_around_register_size, true); +} +// OHOS_LOCAL end + // See the frame breakdown defined in __hwasan_tag_mismatch (from // hwasan_tag_mismatch_aarch64.S). void ReportRegisters(uptr *frame, uptr pc) { diff --git a/compiler-rt/lib/hwasan/hwasan_report.h b/compiler-rt/lib/hwasan/hwasan_report.h index de86c38fc01f2d88bebcacb2b823f8b22894d4e3..9ba8a1f6658b8440287363b20863bdb8c67a8fa1 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.h +++ b/compiler-rt/lib/hwasan/hwasan_report.h @@ -16,6 +16,7 @@ #define HWASAN_REPORT_H #include "sanitizer_common/sanitizer_internal_defs.h" +#include "sanitizer_common/sanitizer_procmaps.h" // OHOS_LOCAL #include "sanitizer_common/sanitizer_stacktrace.h" namespace __hwasan { @@ -27,9 +28,13 @@ void ReportInvalidFree(StackTrace *stack, uptr addr); void ReportTailOverwritten(StackTrace *stack, uptr addr, uptr orig_size, const u8 *expected); void ReportRegisters(uptr *registers_frame, uptr pc); +// OHOS_LOCAL begin +void ReportMemoryNearRegisters(uptr *registers_frame, uptr pc); +void PrintMemoryAroundAddress(MemoryMappingLayout &proc_maps, int reg_num, + uptr addr, uptr len, bool is_pc = false); +// OHOS_LOCAL end void ReportAtExitStatistics(); - } // namespace __hwasan #endif // HWASAN_REPORT_H diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index c776ae179cec2e5ed38b12a9fa3d9ab93a465c68..4be4929284d9247380093fc9db127a5f003ed374 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -44,9 +44,12 @@ void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size, static atomic_uint64_t unique_id; unique_id_ = atomic_fetch_add(&unique_id, 1, memory_order_relaxed); - if (auto sz = flags()->heap_history_size) +// OHOS_LOCAL begin + if (auto sz = IsMainThread() ? flags()->heap_history_size_main_thread + : flags()->heap_history_size) +// OHOS_LOCAL end heap_allocations_ = HeapAllocationsRingBuffer::New(sz); - + trace_heap_allocation_ = true; // OHOS_LOCAL #if !SANITIZER_FUCHSIA // Do not initialize the stack ring buffer just yet on Fuchsia. Threads will // be initialized before we enter the thread itself, so we will instead call @@ -54,6 +57,8 @@ void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size, InitStackRingBuffer(stack_buffer_start, stack_buffer_size); #endif InitStackAndTls(state); + tid_ = GetTid(); // OHOS_LOCAL + heap_quarantine_controller()->Init(); // OHOS_LOCAL } void Thread::InitStackRingBuffer(uptr stack_buffer_start, @@ -96,6 +101,8 @@ void Thread::ClearShadowForThreadStackAndTLS() { void Thread::Destroy() { if (flags()->verbose_threads) Print("Destroying: "); + // OHOS_LOCAL + heap_quarantine_controller()->ClearHeapQuarantine(allocator_cache()); AllocatorSwallowThreadLocalCache(allocator_cache()); ClearShadowForThreadStackAndTLS(); if (heap_allocations_) @@ -110,9 +117,17 @@ void Thread::Destroy() { } void Thread::Print(const char *Prefix) { - Printf("%sT%zd %p stack: [%p,%p) sz: %zd tls: [%p,%p)\n", Prefix, unique_id_, - (void *)this, stack_bottom(), stack_top(), - stack_top() - stack_bottom(), tls_begin(), tls_end()); +// OHOS_LOCAL begin + Printf( + "%sT%zd %p stack: [%p,%p) sz: %zd tls: [%p,%p) rb:(%zd/%u) " + "records(%llu/o:%llu) tid: %d\n", + Prefix, unique_id_, (void *)this, stack_bottom(), stack_top(), + stack_top() - stack_bottom(), tls_begin(), tls_end(), + heap_allocations() ? heap_allocations()->realsize() : 0, + IsMainThread() ? flags()->heap_history_size_main_thread + : flags()->heap_history_size, + all_record_count_, all_record_count_overflow_, tid_); +// OHOS_LOCAL end } static u32 xorshift(u32 state) { @@ -147,4 +162,12 @@ tag_t Thread::GenerateRandomTag(uptr num_bits) { return tag; } +// OHOS_LOCAL begin +bool Thread::TryPutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, + u32 fid) { + return heap_quarantine_controller()->TryPutInQuarantineWithDealloc( + ptr, s, aid, fid, allocator_cache()); +} +// OHOS_LOCAL end + } // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index 3db7c1a9454f30211e637c3023e2911be4f931a6..8f1126877aa92d0df59eeab2c894344d9a1d54aa 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -14,6 +14,7 @@ #define HWASAN_THREAD_H #include "hwasan_allocator.h" +#include "hwasan_quarantine.h" // OHOS_LOCAL #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_ring_buffer.h" @@ -48,6 +49,15 @@ class Thread { uptr tls_end() { return tls_end_; } bool IsMainThread() { return unique_id_ == 0; } +// OHOS_LOCAL begin + void inc_record(void) { + all_record_count_++; + if (all_record_count_ == 0) { + all_record_count_overflow_++; + } + } +// OHOS_LOCAL end + bool AddrIsInStack(uptr addr) { return addr >= stack_bottom_ && addr < stack_top_; } @@ -61,15 +71,29 @@ class Thread { void DisableTagging() { tagging_disabled_++; } void EnableTagging() { tagging_disabled_--; } +// OHOS_LOCAL begin + void EnableTracingHeapAllocation() { trace_heap_allocation_ = true; } + void DisableTracingHeapAllocation() { trace_heap_allocation_ = false; } + bool AllowTracingHeapAllocation() { return trace_heap_allocation_; } +// OHOS_LOCAL end + u64 unique_id() const { return unique_id_; } - void Announce() { - if (announced_) return; - announced_ = true; - Print("Thread: "); - } + +// OHOS_LOCAL begin + int tid() const { return tid_; } + void Announce() { Print("Thread: "); } +// OHOS_LOCAL end uptr &vfork_spill() { return vfork_spill_; } +// OHOS_LOCAL begin + HeapQuarantineController *heap_quarantine_controller() { + return &heap_quarantine_controller_; + } + + bool TryPutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, u32 fid); +// OHOS_LOCAL end + private: // NOTE: There is no Thread constructor. It is allocated // via mmap() and *must* be valid in zero-initialized state. @@ -89,6 +113,9 @@ class Thread { HeapAllocationsRingBuffer *heap_allocations_; StackAllocationsRingBuffer *stack_allocations_; +// OHOS_LOCAL + HeapQuarantineController heap_quarantine_controller_; + u64 unique_id_; // counting from zero. u32 tagging_disabled_; // if non-zero, malloc uses zero tag in this thread. @@ -97,6 +124,15 @@ class Thread { bool random_state_inited_; // Whether InitRandomState() has been called. +// OHOS_LOCAL begin + bool trace_heap_allocation_; + + int tid_ = -1; // Thread ID + + u64 all_record_count_ = 0; // Count record + u64 all_record_count_overflow_ = 0; // Whether all_record_count_ overflow. +// OHOS_LOCAL end + friend struct ThreadListHead; }; diff --git a/compiler-rt/lib/hwasan/hwasan_thread_list.h b/compiler-rt/lib/hwasan/hwasan_thread_list.h index 15916a802d6ee4c50c6189ad144d195f86ceba78..e039854ccaf83567ac71bd1723333752fa263c82 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread_list.h +++ b/compiler-rt/lib/hwasan/hwasan_thread_list.h @@ -83,6 +83,16 @@ class HwasanThreadList { ring_buffer_size_ = RingBufferSize(); thread_alloc_size_ = RoundUpTo(ring_buffer_size_ + sizeof(Thread), ring_buffer_size_ * 2); +// OHOS_LOCAL begin + freed_rb_fallback_ = + HeapAllocationsRingBuffer::New(flags()->heap_history_size_main_thread); + + freed_rb_list_ = nullptr; + freed_rb_list_size_ = 0; + freed_rb_count_ = 0; + freed_rb_count_overflow_ = 0; + trace_heap_allocation_ = true; +// OHOS_LOCAL end } Thread *CreateCurrentThread(const Thread::InitState *state = nullptr) { @@ -127,7 +137,55 @@ class HwasanThreadList { CHECK(0 && "thread not found in live list"); } +// OHOS_LOCAL begin + void AddFreedRingBuffer(Thread *t) { + if (t->heap_allocations() == nullptr || + t->heap_allocations()->realsize() == 0) + return; + + SpinMutexLock l(&freed_rb_mutex_); + if (!freed_rb_list_) { + size_t sz = flags()->freed_threads_history_size * + sizeof(HeapAllocationsRingBuffer *); + freed_rb_list_ = reinterpret_cast( + MmapOrDie(sz, "FreedRingBufferList")); + if (UNLIKELY(freed_rb_list_ == nullptr)) { + return; + } + } + if (freed_rb_list_size_ >= flags()->freed_threads_history_size) { + auto sz = flags()->freed_threads_history_size / 3; + for (uptr i = 0; i < sz; i++) { + if (freed_rb_list_[i]) + freed_rb_list_[i]->Delete(); + } + auto left = flags()->freed_threads_history_size - sz; + for (uptr i = 0; i < left; i++) { + freed_rb_list_[i] = freed_rb_list_[i + sz]; + } + freed_rb_list_size_ = left; + } + HeapAllocationsRingBuffer *freed_allocations_; + freed_allocations_ = HeapAllocationsRingBuffer::New( + t->IsMainThread() ? flags()->heap_history_size_main_thread + : flags()->heap_history_size); + + HeapAllocationsRingBuffer *rb = t->heap_allocations(); + for (uptr i = 0, size = rb->realsize(); i < size; i++) { + HeapAllocationRecord h = (*rb)[i]; + freed_allocations_->push({h.tagged_addr, h.alloc_context_id, + h.free_context_id, h.requested_size}); + } + freed_rb_list_[freed_rb_list_size_] = freed_allocations_; + freed_rb_list_size_++; + freed_rb_count_++; + if (freed_rb_count_ == 0) + freed_rb_count_overflow_++; + } +// OHOS_LOCAL end + void ReleaseThread(Thread *t) { + AddFreedRingBuffer(t); // OHOS_LOCAL RemoveThreadStats(t); t->Destroy(); DontNeedThread(t); @@ -154,6 +212,28 @@ class HwasanThreadList { for (Thread *t : live_list_) cb(t); } +// OHOS_LOCAL begin + template + void VisitAllFreedRingBuffer(CB cb) { + DisableTracingHeapAllocation(); + SpinMutexLock l(&freed_rb_mutex_); + for (size_t i = 0; i < freed_rb_list_size_; i++) { + cb(freed_rb_list_[i]); + } + if (freed_rb_fallback_) + cb(freed_rb_fallback_); + EnableTracingHeapAllocation(); + } + + void PrintFreedRingBufferSummary(void) { + SpinMutexLock l(&freed_rb_mutex_); + Printf("freed thread count: %llu, overflow %llu, %zd left\n", + freed_rb_count_, freed_rb_count_overflow_, freed_rb_list_size_); + if (freed_rb_fallback_) + Printf("fallback count: %llu\n", freed_rb_fallback_->realsize()); + } +// OHOS_LOCAL end + void AddThreadStats(Thread *t) { SpinMutexLock l(&stats_mutex_); stats_.n_live_threads++; @@ -173,6 +253,18 @@ class HwasanThreadList { uptr GetRingBufferSize() const { return ring_buffer_size_; } +// OHOS_LOCAL begin + void RecordFallBack(HeapAllocationRecord h) { + SpinMutexLock l(&freed_rb_mutex_); + if (freed_rb_fallback_) + freed_rb_fallback_->push(h); + } + + void EnableTracingHeapAllocation() { trace_heap_allocation_ = true; } + void DisableTracingHeapAllocation() { trace_heap_allocation_ = false; } + bool AllowTracingHeapAllocation() { return trace_heap_allocation_; } +// OHOS_LOCAL end + private: Thread *AllocThread() { SpinMutexLock l(&free_space_mutex_); @@ -195,6 +287,16 @@ class HwasanThreadList { SpinMutex live_list_mutex_; InternalMmapVector live_list_; +// OHOS_LOCAL begin + SpinMutex freed_rb_mutex_; + HeapAllocationsRingBuffer **freed_rb_list_; + HeapAllocationsRingBuffer *freed_rb_fallback_; + size_t freed_rb_list_size_; + u64 freed_rb_count_; + u64 freed_rb_count_overflow_; + bool trace_heap_allocation_; +// OHOS_LOCAL end + ThreadStats stats_; SpinMutex stats_mutex_; }; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index ed20388016fb10c6908a5315b7a2ba3b6512b97c..1b4f1bf45084233e308973a60cdbe2c1181f6081 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -229,6 +229,7 @@ bool ColorizeReports(); void RemoveANSIEscapeSequencesFromString(char *buffer); void Printf(const char *format, ...) FORMAT(1, 2); void Report(const char *format, ...) FORMAT(1, 2); +bool IsInPrintf(); // OHOS_LOCAL void SetPrintfAndReportCallback(void (*callback)(const char *)); #define VReport(level, ...) \ do { \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp index 6769d49ee12951366c4dd4f40b223d3f6180a6d7..0c7149c01c148d17cb27dae2787fee7cf73c30b8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp @@ -93,7 +93,7 @@ static void RecursiveCreateParentDirs(char *path) { if (!IsPathSeparator(path[i])) continue; path[i] = '\0'; - if (!DirExists(path) && !CreateDir(path)) { + if (common_flags()->check_log_path_on_init && !DirExists(path) && !CreateDir(path)) { // OHOS_LOCAL const char *ErrorMsgPrefix = "ERROR: Can't create directory: "; WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix)); WriteToFile(kStderrFd, path, internal_strlen(path)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index 509bcf6afd1af8dc6f0c5b0376aed036e2749c24..15a253feb1168371961a2e16032a9c6e8287fdcf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -19,6 +19,12 @@ // Default value must be a compile-time constant. // Description must be a string literal. +// OHOS_LOCAL begin +COMMON_FLAG( + bool, check_log_path_on_init, true, + "If set, log_path will be checked during initialization.") +// OHOS_LOCAL end + COMMON_FLAG( bool, symbolize, true, "If set, use the online symbolizer from common sanitizer runtime to turn " diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index ec874e50adc446e41de36e7622677fdc011ac59f..689a94deccc0b0869081d0073cc265ea1103d9ee 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -36,6 +36,12 @@ #include #include +// OHOS_LOCAL begin +#if SANITIZER_OHOS +#include +#endif +// OHOS_LOCAL end + #if SANITIZER_FREEBSD // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before // that, it was never implemented. So just define it to zero. @@ -195,6 +201,7 @@ static void MaybeInstallSigaction(int signum, SignalHandlerType handler) { if (GetHandleSignalMode(signum) == kHandleSignalNo) return; +#if !SANITIZER_OHOS struct sigaction sigact; internal_memset(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = (sa_sigaction_t)handler; @@ -204,6 +211,20 @@ static void MaybeInstallSigaction(int signum, if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK; CHECK_EQ(0, internal_sigaction(signum, &sigact, nullptr)); VReport(1, "Installed the sigaction for signal %d\n", signum); +#else +// OHOS_LOCAL begin + typedef bool (*sc)(int, siginfo_t *, void *); + sc h = (sc)handler; + struct signal_chain_action sigchain = { + .sca_sigaction = h, + .sca_mask = {}, + .sca_flags = SA_SIGINFO | SA_NODEFER, + }; + // This is a void function for OHOS. When there are too many registered + // functions, an internal error is reported. CHECK is not required. + add_special_signal_handler(signum, &sigchain); +// OHOS_LOCAL end +#endif } void InstallDeadlySignalHandlers(SignalHandlerType handler) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp index 3a9e366d2df952a131634f79bea5e08841faa585..53cc149f662c4ff34007252a8332346807b601ee 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp @@ -310,10 +310,16 @@ static void NOINLINE SharedPrintfCode(bool append_pid, const char *format, format, args); } +static thread_local bool is_in_printf; // OHOS_LOCAL + +bool IsInPrintf() { return is_in_printf; } // OHOS_LOCAL + void Printf(const char *format, ...) { va_list args; va_start(args, format); + is_in_printf = true; // OHOS_LOCAL SharedPrintfCode(false, format, args); + is_in_printf =false; // OHOS_LOCAL va_end(args); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h index f22e40cac28409512b8b1541afe6c75aa1353787..d2356d69cf9b393b5b7f44762804ca187db49b3e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h @@ -27,6 +27,7 @@ class RingBuffer { RingBuffer *RB = reinterpret_cast(Ptr); uptr End = reinterpret_cast(Ptr) + SizeInBytes(Size); RB->last_ = RB->next_ = reinterpret_cast(End - sizeof(T)); + RB->full_ = false; // OHOS_LOCAL return RB; } void Delete() { @@ -35,11 +36,19 @@ class RingBuffer { uptr size() const { return last_ + 1 - reinterpret_cast(reinterpret_cast(this) + - 2 * sizeof(T *)); + sizeof(RingBuffer) - sizeof(T)); // OHOS_LOCAL } +// OHOS_LOCAL begin + uptr realsize() const { + if (full_) + return size(); + return reinterpret_cast((uptr)last_ - (uptr)next_) / sizeof(T); + } +// OHOS_LOCAL end + static uptr SizeInBytes(uptr Size) { - return Size * sizeof(T) + 2 * sizeof(T*); + return Size * sizeof(T) + sizeof(RingBuffer) - sizeof(T); // OHOS_LOCAL } uptr SizeInBytes() { return SizeInBytes(size()); } @@ -48,8 +57,10 @@ class RingBuffer { *next_ = t; next_--; // The condition below works only if sizeof(T) is divisible by sizeof(T*). - if (next_ <= reinterpret_cast(&next_)) + if (next_ <= reinterpret_cast(&next_)) { next_ = last_; + full_ = true; // OHOS_LOCAL + } } T operator[](uptr Idx) const { @@ -66,11 +77,13 @@ class RingBuffer { RingBuffer(const RingBuffer&) = delete; // Data layout: - // LNDDDDDDDD + // FLNDDDDDDDD + // F: indicates whether the ring buffer is full // D: data elements. // L: last_, always points to the last data element. // N: next_, initially equals to last_, is decremented on every push, // wraps around if it's less or equal than its own address. + bool full_; T *last_; T *next_; T data_[1]; // flexible array. diff --git a/compiler-rt/lib/scudo/CMakeLists.txt b/compiler-rt/lib/scudo/CMakeLists.txt index 31a6976960f766ebc6acd6473afddc5a11bc58cd..31ee06ad36d7fb13226110c06b8b1344bdc6cb42 100644 --- a/compiler-rt/lib/scudo/CMakeLists.txt +++ b/compiler-rt/lib/scudo/CMakeLists.txt @@ -30,6 +30,13 @@ if(ANDROID) endif() endif() +# OHOS_LOCAL begin +if(OHOS) + # OHOS currently uses TSD_EXCLUSIVE with TLS storage in scudo, so disable EmuTLS + list(APPEND SCUDO_CFLAGS -fno-emulated-tls) +endif() +# OHOS_LOCAL end + # The minimal Scudo runtime does not include the UBSan runtime. set(SCUDO_MINIMAL_OBJECT_LIBS RTSanitizerCommonNoTermination diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt index 55e97ac0dadf49ce7438f8042422b16a0e7130a0..ad4a5e303267ed7c8531debc5d9b02e25ed7ff6a 100644 --- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt @@ -44,7 +44,10 @@ list(APPEND SCUDO_LINK_FLAGS -ffunction-sections -fdata-sections -Wl,--gc-sectio append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SCUDO_LINK_FLAGS) append_list_if(CXX_SUPPORTS_UNWINDLIB_NONE_FLAG --unwindlib=none SCUDO_LINK_FLAGS) -if(ANDROID) +# OHOS_LOCAL begin +if(ANDROID OR OHOS) + # OHOS currently uses TSD_EXCLUSIVE with TLS storage in scudo, so disable EmuTLS +# OHOS_LOCAL end list(APPEND SCUDO_CFLAGS -fno-emulated-tls) # Put the shared library in the global group. For more details, see diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt index 8200cd2588b35428474987554ab1ef06cf69067f..bff4c771fdb5cfd1bfc89d862eddf3c4611aba6c 100644 --- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt @@ -22,7 +22,10 @@ if(COMPILER_RT_DEBUG) list(APPEND SCUDO_UNITTEST_CFLAGS -DSCUDO_DEBUG=1) endif() -if(ANDROID) +# OHOS_LOCAL begin +if(ANDROID OR OHOS) + # OHOS currently uses TSD_EXCLUSIVE with TLS storage in scudo, so disable EmuTLS +# OHOS_LOCAL end list(APPEND SCUDO_UNITTEST_CFLAGS -fno-emulated-tls) endif() diff --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp index 616cf5491b5e25a9065184d293c6ffcefc03c749..73215df13cdbeec9bc984433d500b10ed59efc3a 100644 --- a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp @@ -20,16 +20,29 @@ #define __GLIBC_PREREQ(x, y) 0 #endif +// OHOS_LOCAL begin extern "C" { void malloc_enable(void); void malloc_disable(void); -int malloc_iterate(uintptr_t base, size_t size, - void (*callback)(uintptr_t base, size_t size, void *arg), - void *arg); void *valloc(size_t size); void *pvalloc(size_t size); } +using MallocIterateBaseT = +#ifdef __OHOS__ + // OHOS has a different function signature + void * +#else + uintptr_t +#endif + ; + +extern "C" int malloc_iterate(MallocIterateBaseT base, size_t size, + void (*callback)(MallocIterateBaseT base, + size_t size, void *arg), + void *arg); +// OHOS_LOCAL end + // Note that every C allocation function in the test binary will be fulfilled // by Scudo (this includes the gtest APIs, etc.), which is a test by itself. // But this might also lead to unexpected side-effects, since the allocation and @@ -301,14 +314,16 @@ TEST(ScudoWrappersCTest, MallInfo2) { static uintptr_t BoundaryP; static size_t Count; -static void callback(uintptr_t Base, size_t Size, void *Arg) { +// OHOS_LOCAL begin +static void callback(MallocIterateBaseT Base, size_t Size, void *Arg) { if (scudo::archSupportsMemoryTagging()) { - Base = scudo::untagPointer(Base); + Base = (MallocIterateBaseT)scudo::untagPointer((uintptr_t)Base); BoundaryP = scudo::untagPointer(BoundaryP); } - if (Base == BoundaryP) + if ((uintptr_t)Base == BoundaryP) Count++; } +// OHOS_LOCAL end // Verify that a block located on an iteration boundary is not mis-accounted. // To achieve this, we allocate a chunk for which the backing block will be @@ -343,8 +358,11 @@ TEST(ScudoWrappersCTest, MallocIterateBoundary) { Count = 0U; malloc_disable(); - malloc_iterate(Block - PageSize, PageSize, callback, nullptr); - malloc_iterate(Block, PageSize, callback, nullptr); + // OHOS_LOCAL begin + malloc_iterate((MallocIterateBaseT)(Block - PageSize), PageSize, callback, + nullptr); + malloc_iterate((MallocIterateBaseT)Block, PageSize, callback, nullptr); + // OHOS_LOCAL end malloc_enable(); EXPECT_EQ(Count, 1U); diff --git a/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py b/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py index 245d434faed9936dd705d887dc861dfd22576e06..269944fc8449539fa6485baf3ee1e4beeac24c7b 100644 --- a/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py +++ b/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py @@ -5,7 +5,7 @@ def getRoot(config): root = getRoot(config) -if root.host_os not in ['Linux', 'FreeBSD', 'NetBSD']: +if root.host_os not in ['Linux', 'FreeBSD', 'NetBSD', 'OHOS']: # OHOS_LOCAL config.unsupported = True # Android O (API level 26) has support for cross-dso cfi in libdl.so. diff --git a/compiler-rt/test/gwp_asan/CMakeLists.txt b/compiler-rt/test/gwp_asan/CMakeLists.txt index 86260027426feb1283385f94290932b9e0ab2f5e..89e8d3edf50ab56f717d0199d69869b4c8235333 100644 --- a/compiler-rt/test/gwp_asan/CMakeLists.txt +++ b/compiler-rt/test/gwp_asan/CMakeLists.txt @@ -14,7 +14,7 @@ set(GWP_ASAN_TEST_DEPS # exported libc++ from the Android NDK is x86-64, even though it's part of the # ARM[64] toolchain... See similar measures for ASan and sanitizer-common that # disable unit tests for Android. -if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_GWP_ASAN AND NOT ANDROID) +if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_GWP_ASAN AND NOT ANDROID AND NOT OHOS) # OHOS_LOCAL list(APPEND GWP_ASAN_TEST_DEPS GwpAsanUnitTests) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.py.in diff --git a/compiler-rt/test/gwp_asan/backtrace.c b/compiler-rt/test/gwp_asan/backtrace.c index f4be7305bfb7ef226734de7eacc2e4c09e93a843..1f8d781d94372bfbd062e0ff95bc00488d25e6d1 100644 --- a/compiler-rt/test/gwp_asan/backtrace.c +++ b/compiler-rt/test/gwp_asan/backtrace.c @@ -28,10 +28,20 @@ __attribute__((noinline)) void touch_mem(void *ptr) { // CHECK: allocate_mem int main() { +// OHOS_LOCAL begin +#ifdef __OHOS__ + // Tested in OHOS, it can be detected with just one execution, without the need for multiple loops. + // If the number of loops is too high, it may cause all slots to be occupied + void *ptr = allocate_mem(); + free_mem(ptr); + touch_mem(ptr); +#else for (unsigned i = 0; i < 0x10000; ++i) { void *ptr = allocate_mem(); free_mem(ptr); touch_mem(ptr); } +#endif +// OHOS_LOCAL end return 0; } diff --git a/compiler-rt/test/gwp_asan/lit.cfg.py b/compiler-rt/test/gwp_asan/lit.cfg.py index 58658a4551dc45f8186b74213b8acf4e47c5daf5..8140916128cf8922201c837a92210a9e164230cb 100644 --- a/compiler-rt/test/gwp_asan/lit.cfg.py +++ b/compiler-rt/test/gwp_asan/lit.cfg.py @@ -44,7 +44,12 @@ config.substitutions.append(( # Platform-specific default GWP_ASAN for lit tests. Ensure that GWP-ASan is # enabled and that it samples every allocation. -default_gwp_asan_options = 'GWP_ASAN_Enabled=1:GWP_ASAN_SampleRate=1' +if config.host_os == 'OHOS': # OHOS_LOCAL + # The default value for GWP_ASAN_MaxSimulataneousAllocations is 16, which is not sufficient for gwp-asan testing + # in OHOS, resulting in many test cases being unable to trigger gwp-asan detection. + default_gwp_asan_options = 'GWP_ASAN_Enabled=1:GWP_ASAN_SampleRate=1:GWP_ASAN_MaxSimultaneousAllocations=500' +else: + default_gwp_asan_options = 'GWP_ASAN_Enabled=1:GWP_ASAN_SampleRate=1' config.environment['SCUDO_OPTIONS'] = default_gwp_asan_options default_gwp_asan_options += ':' diff --git a/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c b/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c index 5a9208809477f15198cdf665c278a6608536f94f..011bc96818a8e6af3124ade7428dff7cc54f41d3 100644 --- a/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c +++ b/compiler-rt/test/hwasan/TestCases/Linux/decorate-proc-maps.c @@ -51,5 +51,5 @@ int main(void) { void * volatile res2 = malloc(100000); pthread_create(&t, 0, ThreadFn, 0); pthread_join(t, 0); - return (int)(size_t)res; + return 0; // OHOS_LOCAL } diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c index ff52a4bf298c613623ff233d054af6cdf2e5b134..8bbf1eb9a3969dca97e232d3f288357ed4a8d4ef 100644 --- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c +++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c @@ -50,10 +50,18 @@ int main(int argc, char **argv) { // CHECKm30: is located 30 bytes to the left of 30-byte region // // CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30 +// OHOS_LOCAL begin +// CHECKMm30: Currently allocated here: +// CHECKMm30: #0 {{[0x]+}}{{.*}} +// OHOS_LOCAL end // CHECKMm30: Cause: heap-buffer-overflow // CHECKMm30: is located 30 bytes to the left of 1000000-byte region // // CHECKM: is a large allocated heap chunk; size: 1003520 offset: 1000000 +// OHOS_LOCAL begin +// CHECKM: Currently allocated here: +// CHECKM: #0 {{[0x]+}}{{.*}} +// OHOS_LOCAL end // CHECKM: Cause: heap-buffer-overflow // CHECKM: is located 0 bytes to the right of 1000000-byte region // diff --git a/compiler-rt/test/hwasan/TestCases/rich-stack.c b/compiler-rt/test/hwasan/TestCases/rich-stack.c index c6c2f9bca66915abd0fb9b3b41dcea91be3b18fd..8f9f0834d56bdba5f8a9526854ce10fa67f3b225 100644 --- a/compiler-rt/test/hwasan/TestCases/rich-stack.c +++ b/compiler-rt/test/hwasan/TestCases/rich-stack.c @@ -64,4 +64,5 @@ int main(int argc, char **argv) { // R321: in BAR // R321-NEXT: in FOO // R321-NEXT: in main -// R321: is located in stack of thread T0 +// OHOS_LOCAL +// R321: is located in stack of thread {{.*}} diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar.c b/compiler-rt/test/hwasan/TestCases/stack-uar.c index 3663eac5d2685897bd7d31cc1dcf1913bcb62b32..8d01fdecc8f537e061b9972890165589fd36062b 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar.c @@ -38,14 +38,16 @@ int main() { // CHECK: is located in stack of thread // CHECK: Potentially referenced stack objects: // CHECK-NEXT: zzz in buggy {{.*}}stack-uar.c:[[@LINE-20]] - // CHECK-NEXT: Memory tags around the buggy address + // OHOS_LOCAL + // CHECK: Memory tags around the buggy address // NOSYM: Previously allocated frames: // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} - // NOSYM-NEXT: Memory tags around the buggy address + // OHOS_LOCAL + // NOSYM: Memory tags around the buggy address // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main } diff --git a/compiler-rt/test/hwasan/TestCases/stack-uas.c b/compiler-rt/test/hwasan/TestCases/stack-uas.c index ca81663e00e6c250fc693726f04d092e7e26f591..096347479dcf4ae8cc9777290075e8efef2fc202 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uas.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uas.c @@ -17,10 +17,6 @@ // Stack histories currently are not recorded on x86. // XFAIL: x86_64 -// OHOS_LOCAL -// Return value is undefined on OHOS -// XFAIL: ohos_family - void USE(void *x) { // pretend_to_do_something(void *x) __asm__ __volatile__("" : @@ -62,14 +58,16 @@ int main() { // CHECK: is located in stack of thread // CHECK: Potentially referenced stack objects: // CHECK-NEXT: zzz in buggy {{.*}}stack-uas.c:[[@LINE-17]] - // CHECK-NEXT: Memory tags around the buggy address + // OHOS_LOCAL + // CHECK: Memory tags around the buggy address // NOSYM: Previously allocated frames: // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} - // NOSYM-NEXT: Memory tags around the buggy address + // OHOS_LOCAL + // NOSYM: Memory tags around the buggy address // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy } diff --git a/compiler-rt/test/hwasan/TestCases/thread-uaf.c b/compiler-rt/test/hwasan/TestCases/thread-uaf.c index c368882f45896f5692cb5c7ead7ae1ced5402c90..dd98013b388f7135248affc36f5663b38fb36880 100644 --- a/compiler-rt/test/hwasan/TestCases/thread-uaf.c +++ b/compiler-rt/test/hwasan/TestCases/thread-uaf.c @@ -28,12 +28,15 @@ void *Deallocate(void *arg) { void *Use(void *arg) { x[5] = 42; // CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address - // CHECK: WRITE of size 1 {{.*}} in thread T3 - // CHECK: thread-uaf.c:[[@LINE-3]] + // OHOS_LOCAL + // CHECK: WRITE of size 1 {{.*}} in thread {{.*}} + // CHECK: thread-uaf.c:[[@LINE-4]] // CHECK: Cause: use-after-free - // CHECK: freed by thread T2 here + // OHOS_LOCAL + // CHECK: freed by thread {{.*}} here // CHECK: in Deallocate - // CHECK: previously allocated here: + // OHOS_LOCAL + // CHECK: previously allocated by thread {{.*}} here: // CHECK: in Allocate // CHECK-DAG: Thread: T2 0x // CHECK-DAG: Thread: T3 0x diff --git a/compiler-rt/test/hwasan/TestCases/use-after-free-and-overflow.c b/compiler-rt/test/hwasan/TestCases/use-after-free-and-overflow.c index c08b00fc35ace6cc28b6786a200e5f386ad8da9a..acdee4762df9d9a29b560f0e2bf142b46430763d 100644 --- a/compiler-rt/test/hwasan/TestCases/use-after-free-and-overflow.c +++ b/compiler-rt/test/hwasan/TestCases/use-after-free-and-overflow.c @@ -58,4 +58,5 @@ int main(int argc, char **argv) { // CHECK-NOT: Cause: heap-buffer-overflow // CHECK: Cause: use-after-free -// CHECK-NOT: Cause: heap-buffer-overflow +// OHOS_LOCAL +// CHECK: Cause: heap-buffer-overflow diff --git a/compiler-rt/test/hwasan/TestCases/wild-free-close.c b/compiler-rt/test/hwasan/TestCases/wild-free-close.c index 51eb949dcdc94e9717716b36403746baca4ca9ae..34bc0192bf159202392f3b868cf2993ce2eea385 100644 --- a/compiler-rt/test/hwasan/TestCases/wild-free-close.c +++ b/compiler-rt/test/hwasan/TestCases/wild-free-close.c @@ -11,9 +11,10 @@ int main() { fprintf(stderr, "ALLOC %p\n", __hwasan_tag_pointer(p, 0)); // CHECK: ALLOC {{[0x]+}}[[ADDR:.*]] free(p - 8); - // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{.*}} at pc {{[0x]+}}[[PC:.*]] on thread T{{[0-9]+}} + // OHOS_LOCAL + // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{.*}} at pc {{[0x]+}}[[PC:.*]] on thread {{.*}} // CHECK: #0 {{[0x]+}}{{.*}}[[PC]] in {{.*}}free - // CHECK: #1 {{.*}} in main {{.*}}wild-free-close.c:[[@LINE-3]] + // CHECK: #1 {{.*}} in main {{.*}}wild-free-close.c:[[@LINE-4]] // CHECK: is located 8 bytes to the left of 1-byte region [{{[0x]+}}{{.*}}[[ADDR]] // CHECK-NOT: Segmentation fault // CHECK-NOT: SIGSEGV diff --git a/compiler-rt/test/hwasan/TestCases/wild-free-realloc.c b/compiler-rt/test/hwasan/TestCases/wild-free-realloc.c index 19d2943e4c51c2c914eccb2f6c862e5e8f80f90a..8f47e46fca1f3be50bfe7fe900171a7b251b8d19 100644 --- a/compiler-rt/test/hwasan/TestCases/wild-free-realloc.c +++ b/compiler-rt/test/hwasan/TestCases/wild-free-realloc.c @@ -7,9 +7,10 @@ int main() { __hwasan_enable_allocator_tagging(); char *p = (char *)malloc(1); realloc(p + 0x10000000000, 2); - // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{.*}} at pc {{[0x]+}}[[PC:.*]] on thread T{{[0-9]+}} + // OHOS_LOCAL + // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{.*}} at pc {{[0x]+}}[[PC:.*]] on thread {{.*}} // CHECK: #0 {{[0x]+}}{{.*}}[[PC]] in {{.*}}realloc - // CHECK: #1 {{.*}} in main {{.*}}wild-free-realloc.c:[[@LINE-3]] + // CHECK: #1 {{.*}} in main {{.*}}wild-free-realloc.c:[[@LINE-4]] // CHECK-NOT: Segmentation fault // CHECK-NOT: SIGSEGV return 0; diff --git a/compiler-rt/test/hwasan/TestCases/wild-free-shadow.c b/compiler-rt/test/hwasan/TestCases/wild-free-shadow.c index 7810e26dfffd1f5d6ea9b8a0dc33565f978c87b9..a6cd82443247c8b4616c311f8d59efc36f8664ac 100644 --- a/compiler-rt/test/hwasan/TestCases/wild-free-shadow.c +++ b/compiler-rt/test/hwasan/TestCases/wild-free-shadow.c @@ -7,9 +7,10 @@ extern void *__hwasan_shadow_memory_dynamic_address; int main() { char *p = (char *)malloc(1); free(__hwasan_shadow_memory_dynamic_address); - // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{[0x]+}}[[PTR:.*]] at pc {{[0x]+}}[[PC:.*]] on thread T{{[0-9]+}} + // OHOS_LOCAL + // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{[0x]+}}[[PTR:.*]] at pc {{[0x]+}}[[PC:.*]] on thread {{.*}} // CHECK: #0 {{[0x]+}}{{.*}}[[PC]] in {{.*}}free - // CHECK: #1 {{.*}} in main {{.*}}wild-free-shadow.c:[[@LINE-3]] + // CHECK: #1 {{.*}} in main {{.*}}wild-free-shadow.c:[[@LINE-4]] // CHECK: {{[0x]+}}{{.*}}[[PTR]] is HWAsan shadow memory. // CHECK-NOT: Segmentation fault // CHECK-NOT: SIGSEGV diff --git a/compiler-rt/test/hwasan/TestCases/wild-free.c b/compiler-rt/test/hwasan/TestCases/wild-free.c index a38822c2f8609b1aeba25141ec19f736a93e39c2..50678142089b21a789e531f7b0f83bb25c8434ed 100644 --- a/compiler-rt/test/hwasan/TestCases/wild-free.c +++ b/compiler-rt/test/hwasan/TestCases/wild-free.c @@ -7,9 +7,10 @@ int main() { __hwasan_enable_allocator_tagging(); char *p = (char *)malloc(1); free(p + 0x10000000000); - // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{.*}} at pc {{[0x]+}}[[PC:.*]] on thread T{{[0-9]+}} + // OHOS_LOCAL + // CHECK: ERROR: HWAddressSanitizer: invalid-free on address {{.*}} at pc {{[0x]+}}[[PC:.*]] on thread {{.*}} // CHECK: #0 {{[0x]+}}{{.*}}[[PC]] in {{.*}}free - // CHECK: #1 {{.*}} in main {{.*}}wild-free.c:[[@LINE-3]] + // CHECK: #1 {{.*}} in main {{.*}}wild-free.c:[[@LINE-4]] // CHECK-NOT: Segmentation fault // CHECK-NOT: SIGSEGV return 0; diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index 53a9df0252c656ed9fc11985c9d1cced84050719..3d7d3442b086b84df5a857c82e1b65fc2d23a701 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -626,7 +626,7 @@ def is_windows_lto_supported(): if config.host_os == 'Darwin' and is_darwin_lto_supported(): config.lto_supported = True config.lto_flags = [ '-Wl,-lto_library,' + liblto_path() ] -elif config.host_os in ['Linux', 'FreeBSD', 'NetBSD']: +elif config.host_os in ['Linux', 'FreeBSD', 'NetBSD', 'OHOS']: # OHOS_LOCAL config.lto_supported = False if config.use_lld: config.lto_supported = True diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in index c010b35b3ee73eddf041f8c798552dc2d5293a2b..5afa0c69dfe604065687aae027e7fc88506587f9 100755 --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in @@ -28,7 +28,7 @@ def map_list(value, sep, regex, get_path_and_do_push): def build_env(do_push=True): args = [] sanitizers = ( - 'HWASAN', 'ASAN', 'LSAN', 'MEMPROF', 'MSAN', 'TSAN', 'UBSAN', 'SCUDO' + 'HWASAN', 'ASAN', 'LSAN', 'MEMPROF', 'MSAN', 'TSAN', 'UBSAN', 'SCUDO', 'GWP_ASAN' ) set_abort_on_error=True for san in sanitizers: @@ -46,10 +46,11 @@ def build_env(do_push=True): args.append('%s=%s' % (symb_name, os.environ.get('LLVM_SYMBOLIZER_PATH', os.path.join(TMPDIR,'llvm-symbolizer-aarch64')))) # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. - args.append('LD_LIBRARY_PATH=%s' % ( TMPDIR,)) + os.environ['LD_LIBRARY_PATH'] = '%s:%s' % (os.environ.get('LD_LIBRARY_PATH', ''), TMPDIR) for (key, value) in os.environ.items(): san_opt = key.endswith('SAN_OPTIONS') - if san_opt and set_abort_on_error: + if san_opt and key != 'GWP_ASAN_OPTIONS' and set_abort_on_error: + # GWP_ASAN doesn't have abort_on_error option value += ':abort_on_error=0' if key in ['ASAN_ACTIVATION_OPTIONS', 'SCUDO_OPTIONS'] or san_opt or key == 'LD_LIBRARY_PATH': if key in ['TSAN_OPTIONS', 'UBSAN_OPTIONS']: diff --git a/compiler-rt/test/sanitizer_common/remote_interfaces/hdc.py b/compiler-rt/test/sanitizer_common/remote_interfaces/hdc.py index c99f73b77cc1b9c4ba54d85605afd41d4268d00e..ab8c0c4d0dab83204eabbf3936a3055cf4afaf4f 100644 --- a/compiler-rt/test/sanitizer_common/remote_interfaces/hdc.py +++ b/compiler-rt/test/sanitizer_common/remote_interfaces/hdc.py @@ -61,7 +61,7 @@ def pull_from_device(path): tmp = tempfile.mktemp() hdc(['file', 'recv', path, tmp], attempts=5, check_stdout='FileTransfer finish') - text = open(tmp, 'r').read() + text = open(tmp, 'r', errors='replace').read() os.unlink(tmp) return text diff --git a/compiler-rt/test/scudo/rss.c b/compiler-rt/test/scudo/rss.c index 7f182b6dd6e5e504381b4dbc95365dca2e4e8136..dbe07f551563e211823b40b8234e7fcf18944951 100644 --- a/compiler-rt/test/scudo/rss.c +++ b/compiler-rt/test/scudo/rss.c @@ -22,6 +22,12 @@ #include #include +// OHOS_LOCAL begin +#ifdef __OHOS__ +# include +#endif +// OHOS_LOCAL end + static const size_t kNumAllocs = 64; static const size_t kAllocSize = 1 << 20; // 1MB. @@ -41,10 +47,16 @@ int main(int argc, char *argv[]) { } for (int i = 0; i < kNumAllocs; i++) free(allocs[i]); + // OHOS_LOCAL begin +#ifdef __OHOS__ + // remove the RSS limit, in case RSS check is not caught up and EmuTLS is in libc internals + __scudo_set_rss_limit(0, 0); +#endif if (returned_null == 0) - printf("All malloc calls succeeded\n"); + fprintf(stderr, "All malloc calls succeeded\n"); else - printf("%d malloc calls returned NULL\n", returned_null); + fprintf(stderr, "%d malloc calls returned NULL\n", returned_null); + // OHOS_LOCAL end return 0; } diff --git a/compiler-rt/test/scudo/tsd_destruction.c b/compiler-rt/test/scudo/tsd_destruction.c index 2964df99745b32adf46fa3609db99727c4ed274c..898f9dd7b86e0cbe2870db86054229668d5f0d6c 100644 --- a/compiler-rt/test/scudo/tsd_destruction.c +++ b/compiler-rt/test/scudo/tsd_destruction.c @@ -28,7 +28,11 @@ void *thread_func(void *arg) { if ((i & 1) == 0) free(malloc(16)); // Calling strerror_l allows for strerror_thread_freeres to be called. - strerror_l(0, LC_GLOBAL_LOCALE); + // OHOS_LOCAL begin + locale_t locale = duplocale(LC_GLOBAL_LOCALE); + strerror_l(0, locale); + freelocale(locale); + // OHOS_LOCAL end return 0; } diff --git a/compiler-rt/test/ubsan/CMakeLists.txt b/compiler-rt/test/ubsan/CMakeLists.txt index 749446320ff3c87f9d35200770f5178f8780a486..d07d86b66ea2cf780c5d34081de19b8205b9152c 100644 --- a/compiler-rt/test/ubsan/CMakeLists.txt +++ b/compiler-rt/test/ubsan/CMakeLists.txt @@ -41,6 +41,10 @@ if(APPLE) darwin_filter_host_archs(UBSAN_SUPPORTED_ARCH UBSAN_TEST_ARCH) endif() +# OHOS_LOCAL begin +set(SUPPORT_MULTI_SAN !OHOS_FAMILY) +# OHOS_LOCAL end + foreach(arch ${UBSAN_TEST_ARCH}) set(UBSAN_TEST_TARGET_ARCH ${arch}) if (APPLE) @@ -50,7 +54,9 @@ foreach(arch ${UBSAN_TEST_ARCH}) get_test_cc_for_arch(${arch} UBSAN_TEST_TARGET_CC UBSAN_TEST_TARGET_CFLAGS) add_ubsan_testsuites("Standalone" ubsan ${arch}) - if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + # OHOS_LOCAL begin + if(SUPPORT_MULTI_SAN AND COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + # OHOS_LOCAL end # TODO(wwchrome): Re-enable ubsan for asan win 64-bit when ready. # Disable ubsan with AddressSanitizer tests for Windows 64-bit, # 64-bit Solaris/x86, and SPARC. @@ -60,10 +66,14 @@ foreach(arch ${UBSAN_TEST_ARCH}) add_ubsan_testsuites("AddressSanitizer" asan ${arch}) endif() endif() - if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + # OHOS_LOCAL begin + if(SUPPORT_MULTI_SAN AND COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + # OHOS_LOCAL end add_ubsan_testsuites("MemorySanitizer" msan ${arch}) endif() - if(COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};" AND NOT ANDROID) + # OHOS_LOCAL begin + if(SUPPORT_MULTI_SAN AND COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};" AND NOT ANDROID) + # OHOS_LOCAL end add_ubsan_testsuites("ThreadSanitizer" tsan ${arch}) endif() endforeach() diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig index 3c2cd85f504da91d4373a47d71e7c1505308b738..fe1bcd3e4cc663dbdba29d14bfba25e154b0fddc 100644 --- a/lldb/bindings/headers.swig +++ b/lldb/bindings/headers.swig @@ -41,6 +41,7 @@ #include "lldb/API/SBListener.h" #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBMemoryRegionInfoList.h" +#include "lldb/API/SBMixedArkTSDebugger.h" /* OHOS_LOCAL */ #include "lldb/API/SBModule.h" #include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" diff --git a/lldb/bindings/interface/SBMixedArkTSDebugger.i b/lldb/bindings/interface/SBMixedArkTSDebugger.i new file mode 100644 index 0000000000000000000000000000000000000000..11bb629f7eaf18ca5ae4174a7a6951680cbed465 --- /dev/null +++ b/lldb/bindings/interface/SBMixedArkTSDebugger.i @@ -0,0 +1,40 @@ +//===-- SWIG Interface for SBMixedArkTSDebugger -----------------*- C++ -*-===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +%feature("docstring", +"Represents py:class:`SBMixedArkTSDebugger`. + +SBMixedArkTSDebugger supports OHOS Applications to get ArkTS debug information after +calling napi and during debugging C/C++. + +This class should not be used when ArkTS runtime running. If used, unexpected issue +may occur." +) SBMixedArkTSDebugger; +class SBMixedArkTSDebugger { +public: + SBMixedArkTSDebugger(); + + SBMixedArkTSDebugger(const lldb::SBTarget &rhs); + + SBMixedArkTSDebugger(const lldb::TargetSP &taraget_sp); + + lldb::SBData GetBackTrace(SBError &er); +}; + +} // namespace lldb diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig index c9a6d0f06056864281b42ac9511de00bf7a43c29..6fa25dd8dcaa67ba59100fe4a26382ff70145fba 100644 --- a/lldb/bindings/interfaces.swig +++ b/lldb/bindings/interfaces.swig @@ -48,6 +48,7 @@ %include "./interface/SBListener.i" %include "./interface/SBMemoryRegionInfo.i" %include "./interface/SBMemoryRegionInfoList.i" +%include "./interface/SBMixedArkTSDebugger.i" /* OHOS_LOCAL */ %include "./interface/SBModule.i" %include "./interface/SBModuleSpec.i" %include "./interface/SBPlatform.i" diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index eacbbeafcf1cd8658efba33c0dd536379f2fd0d0..38ab8b94f7ce6b6e661c25e5f59273a00e5a5ac0 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -44,6 +44,7 @@ #include "lldb/API/SBListener.h" #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBMemoryRegionInfoList.h" +#include "lldb/API/SBMixedArkTSDebugger.h" // OHOS_LOCAL #include "lldb/API/SBModule.h" #include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" diff --git a/lldb/include/lldb/API/SBData.h b/lldb/include/lldb/API/SBData.h index 89a699f2f713a0f8c02d0d2e3dbae107595502ea..fa1704a0531a139de945200ae97c5983e75e7c65 100644 --- a/lldb/include/lldb/API/SBData.h +++ b/lldb/include/lldb/API/SBData.h @@ -153,6 +153,7 @@ private: friend class SBSection; friend class SBTarget; friend class SBValue; + friend class SBMixedArkTSDebugger; // OHOS_LOCAL friend class lldb_private::ScriptInterpreter; diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index ecf1dc34d8c5854c0f1ca71b5e073089e5d79470..244ea78046b8e1bdcadf34238017477c0157ec5a 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -68,6 +68,7 @@ class LLDB_API SBLineEntry; class LLDB_API SBListener; class LLDB_API SBMemoryRegionInfo; class LLDB_API SBMemoryRegionInfoList; +class LLDB_API SBMixedArkTSDebugger; // OHOS_LOCAL class LLDB_API SBModule; class LLDB_API SBModuleSpec; class LLDB_API SBModuleSpecList; diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h index f8289e2fcbb3a48916422326c4ccee01b8f99c0b..9ca763404875e2f1cf30e9131c5c2c759f6ec9e1 100644 --- a/lldb/include/lldb/API/SBError.h +++ b/lldb/include/lldb/API/SBError.h @@ -75,6 +75,7 @@ protected: friend class SBValue; friend class SBWatchpoint; friend class SBFile; + friend class SBMixedArkTSDebugger; // OHOS_LOCAL friend class lldb_private::ScriptInterpreter; diff --git a/lldb/include/lldb/API/SBMixedArkTSDebugger.h b/lldb/include/lldb/API/SBMixedArkTSDebugger.h new file mode 100644 index 0000000000000000000000000000000000000000..595fcbfd4a21096449e900622d959f67d5edad6a --- /dev/null +++ b/lldb/include/lldb/API/SBMixedArkTSDebugger.h @@ -0,0 +1,53 @@ +//===-- SBMixedArkTSDebugger.h ----------------------------------*- C++ -*-===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_API_SBMIXEDARKTSDEBUGGER_H +#define LLDB_API_SBMIXEDARKTSDEBUGGER_H + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class LLDB_API SBMixedArkTSDebugger { +public: + SBMixedArkTSDebugger(); + + SBMixedArkTSDebugger(const lldb::SBTarget &rhs); + + SBMixedArkTSDebugger(const lldb::TargetSP &target_sp); + + ~SBMixedArkTSDebugger(); + + /// Get the backtrace of ArkTS for current thread. A cstring which contains + /// the information of backtrace is saved in return. + /// + /// If the current thread does not have an ArkTS runtime, "\0" will be returned. + /// + /// \param [out] er + /// The variable to get error reason, when some error occurred. + /// + /// \return + /// An lldb::SBData object which contain the raw cstring of ArkTS backtrace. + lldb::SBData GetBackTrace(SBError &er); + +private: + lldb_private::MixedArkTSDebugger* m_opaque_ptr; +}; + +} // namespace lldb + +#endif // LLDB_API_SBMIXEDARKTSDEBUGGER_H \ No newline at end of file diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 018acfd595adef1db6297fc7c037df0d5673c80d..086ca63c518c23616eb54f1b7bbe278b05e9f84d 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -879,6 +879,7 @@ protected: friend class SBSymbol; friend class SBValue; friend class SBVariablesOptions; + friend class SBMixedArkTSDebugger; // OHOS_LOCAL // Constructors are private, use static Target::Create function to create an // instance of this class. diff --git a/lldb/include/lldb/Target/MixedArkTSDebugger.h b/lldb/include/lldb/Target/MixedArkTSDebugger.h new file mode 100644 index 0000000000000000000000000000000000000000..464e62b19306e3aa307e8f53886fdb17a806e622 --- /dev/null +++ b/lldb/include/lldb/Target/MixedArkTSDebugger.h @@ -0,0 +1,37 @@ +//===-- MixedArkTSDebugger.h ------------------------------------*- C++ -*-===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_MIXEDDEBUGGER_ARKTS_MIXEDARKTSDEBUGGER_H +#define LLDB_SOURCE_PLUGINS_MIXEDDEBUGGER_ARKTS_MIXEDARKTSDEBUGGER_H + +#include "lldb/Target/MixedDebugger.h" +using namespace lldb; + +namespace lldb_private { + +class MixedArkTSDebugger : public MixedDebugger { +public: + MixedArkTSDebugger(const lldb::TargetSP &target_sp); + + ~MixedArkTSDebugger() {}; + + DataExtractorSP GetCurrentThreadBackTrace(Status &error) override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_MIXEDDEBUGGER_MIXEDDEBUGGER_H diff --git a/lldb/include/lldb/Target/MixedDebugger.h b/lldb/include/lldb/Target/MixedDebugger.h new file mode 100644 index 0000000000000000000000000000000000000000..01f43454a8e6a6300bc30b73bcfc1cd2f474be1c --- /dev/null +++ b/lldb/include/lldb/Target/MixedDebugger.h @@ -0,0 +1,59 @@ +//===-- MixedDebugger.h -----------------------------------------*- C++ -*-===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_MIXEDDEBUGGER_MIXEDDEBUGGER_H +#define LLDB_SOURCE_PLUGINS_MIXEDDEBUGGER_MIXEDDEBUGGER_H + +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-forward.h" + +using namespace lldb; + +namespace lldb_private { + +class MixedDebugger{ +public: + MixedDebugger(const TargetSP &target_sp); + + virtual ~MixedDebugger() {}; + + /// Execute the C API provided by runtime to get debug information. + /// + /// \param [in] expr + /// A cstring of expression which start with "(const char*)". + /// + /// \param [out] error + /// The variable to record error reason. + /// + /// \return + /// A DataExtractorSP contain a cstring which length is less than + /// UINT32_MAX. + DataExtractorSP ExecuteAction(const char* expr, Status &error); + + virtual DataExtractorSP GetCurrentThreadBackTrace(Status &error) = 0; + +protected: + TargetSP m_target_sp; + + MixedDebugger() = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_MIXEDDEBUGGER_MIXEDDEBUGGER_H diff --git a/lldb/include/lldb/Utility/LLDBLog.h b/lldb/include/lldb/Utility/LLDBLog.h index 1252dcc6bc2dd5317bbd153f4b430dcb9ff68e39..024e1b1788b05080651269b4da07c50fe8325c5b 100644 --- a/lldb/include/lldb/Utility/LLDBLog.h +++ b/lldb/include/lldb/Utility/LLDBLog.h @@ -50,7 +50,8 @@ enum class LLDBLog : Log::MaskType { // OHOS_LOCAL begin Performance = Log::ChannelFlag<31>, OnDemand = Log::ChannelFlag<32>, - LLVM_MARK_AS_BITMASK_ENUM(OnDemand), + MixedDebugger = Log::ChannelFlag<33>, + LLVM_MARK_AS_BITMASK_ENUM(MixedDebugger), // OHOS_LOCAL end }; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index c51e1850338fff0616b719e58501a5adaf88861c..4988efbf8bbce3495fb242bd367d4044a229e440 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -124,6 +124,10 @@ class Materializer; class MemoryHistory; class MemoryRegionInfo; class MemoryRegionInfos; +// OHOS_LOCAL begin +class MixedArkTSDebugger; +class MixedDebugger; +// OHOS_LOCAL end class Module; class ModuleList; class ModuleSpec; diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 0f39894cb1fbdbb225e71fb7d1287a812184fc60..4cf7110a781c8eb76d294dd8a95c2d19e5e3f693 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -65,6 +65,7 @@ add_lldb_library(liblldb ${LIBLLDB_LIB_TYPE} ${option_framework} # OHOS_LOCAL SBListener.cpp SBMemoryRegionInfo.cpp SBMemoryRegionInfoList.cpp + SBMixedArkTSDebugger.cpp # OHOS_LOCAL SBModule.cpp SBModuleSpec.cpp SBPlatform.cpp diff --git a/lldb/source/API/SBMixedArkTSDebugger.cpp b/lldb/source/API/SBMixedArkTSDebugger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..148f9e473f9b0893caae49a81de81404de244e2b --- /dev/null +++ b/lldb/source/API/SBMixedArkTSDebugger.cpp @@ -0,0 +1,54 @@ +//===-- SBMixedArkTSDebugger.cpp ------------------------------------------===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBMixedArkTSDebugger.h" +#include "lldb/API/SBData.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBError.h" +#include "lldb/Utility/Instrumentation.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/MixedArkTSDebugger.h" + +using namespace lldb; +using namespace lldb_private; + +SBMixedArkTSDebugger::SBMixedArkTSDebugger() { + LLDB_INSTRUMENT_VA(this); +} + +SBMixedArkTSDebugger::SBMixedArkTSDebugger(const lldb::SBTarget &rhs) + : m_opaque_ptr(new MixedArkTSDebugger(rhs.GetSP())) { + LLDB_INSTRUMENT_VA(this, rhs); +} + +SBMixedArkTSDebugger::SBMixedArkTSDebugger(const lldb::TargetSP &target_sp) + : m_opaque_ptr(new MixedArkTSDebugger(target_sp)) { + LLDB_INSTRUMENT_VA(this, target_sp); +} + +SBMixedArkTSDebugger::~SBMixedArkTSDebugger() { + if (m_opaque_ptr) { + delete m_opaque_ptr; + m_opaque_ptr = nullptr; + } +} + +lldb::SBData SBMixedArkTSDebugger::GetBackTrace(SBError &er) { + LLDB_INSTRUMENT_VA(this, er); + + return SBData(m_opaque_ptr->GetCurrentThreadBackTrace(er.ref())); +} diff --git a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 635dbb14a0271692d21b7105152f23f3b965ab85..6554df539ca3aa44ed2ecb5881a86dbe5425ad02 100644 --- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -20,6 +20,9 @@ #include #include #include +#ifdef __OHOS_FAMILY__ +#include +#endif #include #include @@ -179,8 +182,21 @@ struct ForkLaunchInfo { // Don't close first three entries since they are stdin, stdout and // stderr. + #ifdef __OHOS_FAMILY__ + //OHOS_LOCAL begin + //Also do not close the directory itself since it would be + // closed after iteration. + //Here iter.get_handler() would return a int_ptr type, + //while dirfd() aacepts DIR* type to return the fd, so we use + //reinterpret_cast to cast the iter.get_handler() to DIR*. + int dir_fd = dirfd(reinterpret_cast(iter.get_handler())); + if (fd > 2 && !info.has_action(fd) && fd != error_fd && dir_fd != fd) + //OHOS_LOCAL end + #else if (fd > 2 && !info.has_action(fd) && fd != error_fd) + #endif files_to_close.push_back(fd); + } for (int file_to_close : files_to_close) close(file_to_close); diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index c75a10cf61c146da2e51176c8145c1d91b2cdd05..215f385fc8a9377b889f351ad21296b4b048ddb8 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -21,6 +21,10 @@ add_lldb_library(lldbTarget MemoryHistory.cpp MemoryRegionInfo.cpp MemoryTagMap.cpp + # OHOS_LOCAL begin + MixedArkTSDebugger.cpp + MixedDebugger.cpp + # OHOS_LOCAL end ModuleCache.cpp OperatingSystem.cpp PathMappingList.cpp diff --git a/lldb/source/Target/MixedArkTSDebugger.cpp b/lldb/source/Target/MixedArkTSDebugger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cfe46ec7e41d0347b2eeffdccd393a97fdab1808 --- /dev/null +++ b/lldb/source/Target/MixedArkTSDebugger.cpp @@ -0,0 +1,37 @@ +//===-- MixedArkTSDebugger.cpp --------------------------------------------===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/MixedArkTSDebugger.h" +#include "lldb/Utility/LLDBLog.h" + +using namespace lldb; +using namespace lldb_private; + +static const char* BackTrace = "(const char*)GetJsBacktrace()"; + +MixedArkTSDebugger::MixedArkTSDebugger(const TargetSP &target_sp) + : MixedDebugger(target_sp) {} + +DataExtractorSP MixedArkTSDebugger::GetCurrentThreadBackTrace(Status &error) { + DataExtractorSP result = ExecuteAction(BackTrace, error); + if (!error.Success()) { + Log *log = GetLog(LLDBLog::MixedDebugger); + LLDB_LOGF(log, "[MixedArkTSDebugger::GetBackTrace] failed for %s", + error.AsCString()); + } + return result; +} diff --git a/lldb/source/Target/MixedDebugger.cpp b/lldb/source/Target/MixedDebugger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c21ac062592b02985949e65e6e1740c6d619cbc --- /dev/null +++ b/lldb/source/Target/MixedDebugger.cpp @@ -0,0 +1,94 @@ +//===-- MixedDebugger.cpp -------------------------------------------------===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/MixedDebugger.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/DataExtractor.h" + +using namespace lldb; +using namespace lldb_private; + +MixedDebugger::MixedDebugger(const TargetSP &target_sp) : m_target_sp(target_sp) {} + +DataExtractorSP MixedDebugger::ExecuteAction(const char* expr, Status &error) { + Log *log = GetLog(LLDBLog::MixedDebugger); + error.Clear(); + ValueObjectSP expr_value_sp; + TargetSP target_sp(m_target_sp); + DataExtractorSP result(new DataExtractor()); + + if (m_target_sp) { + if (expr == nullptr || expr[0] == 0) { + error.SetErrorString("Expression is empty"); + return result; + } + + std::lock_guard guard(target_sp->GetAPIMutex()); + ExecutionContext exe_ctx(target_sp.get()); + + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + + if (target) { + lldb::ExpressionResults expr_re = + target->EvaluateExpression(expr, frame, expr_value_sp); + if (expr_re) { + error.SetErrorStringWithFormat( + "[MixedDebugger::ExecuteAction] exe %s failed: %d", expr, expr_re); + return result; + } + + const size_t k_max_buf_size = 64; + size_t cstr_len = UINT32_MAX; + size_t offset = 0; + size_t bytes_read = 0; + DataExtractor data; + while ((bytes_read = expr_value_sp->GetPointeeData(data, offset, k_max_buf_size)) > 0) { + const char *cstr = data.PeekCStr(0); + size_t len = strnlen(cstr, k_max_buf_size); + if (len >= cstr_len) { + error.SetErrorString("[MixedDebugger::ExecuteAction] result over size"); + result->Clear(); + return result; + } + if (!result->Append(const_cast(cstr), len)) { + error.SetErrorString("[MixedDebugger::ExecuteAction] result append data failed"); + result->Clear(); + return result; + } + if (len < k_max_buf_size) { + break; + } + cstr_len -= len; + offset += len; + } + + // Add terminator to result data + char te = '\0'; + if (!result->Append(&te, 1)) { + error.SetErrorString("[MixedDebugger::ExecuteAction] result append terminator failed"); + result->Clear(); + return result; + } + } + } + LLDB_LOGF(log, + "[MixedDebugger::ExecuteAction] result is " + "%s", result->PeekCStr(0)); + return result; +} diff --git a/lldb/test/API/functionalities/mixed_debugger/arkts/Makefile b/lldb/test/API/functionalities/mixed_debugger/arkts/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..651ab44223196307e56e783c9bdab1d3f20eee0a --- /dev/null +++ b/lldb/test/API/functionalities/mixed_debugger/arkts/Makefile @@ -0,0 +1,16 @@ +# Copyright (C) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +C_SOURCES = main.c + +include Makefile.rules diff --git a/lldb/test/API/functionalities/mixed_debugger/arkts/TestMixedArktsDebugger.py b/lldb/test/API/functionalities/mixed_debugger/arkts/TestMixedArktsDebugger.py new file mode 100644 index 0000000000000000000000000000000000000000..6560d9261f0549c565f0c304481904672202a901 --- /dev/null +++ b/lldb/test/API/functionalities/mixed_debugger/arkts/TestMixedArktsDebugger.py @@ -0,0 +1,84 @@ +""" +Copyright (C) 2024 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class MixedArkTSDebuggerTest(TestBase): + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number for our breakpoint. + self.breakpoint = line_number('main.c', '// break on this line') + + def test(self): + """Test getting js backtrace.""" + self.build() + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.breakpoint, num_expected_locations=1) + + # The breakpoint list should show 1 location. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % + self.breakpoint]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Get the target and process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # Get arkts backtrace + arkdb = lldb.SBMixedArkTSDebugger(target) + er = lldb.SBError() + bt = arkdb.GetBackTrace(er) + + # Check the result + self.assertTrue(er.Success(), "ArkTS debugger get backtrace failed.") + er.Clear() + self.assertTrue(bt.GetString(er, 0) == 'This is a ArkTS backtrace', + 'ArkTS debugger get wrong backtrace.') + + # Run to completion + self.runCmd("continue") + + # If the process hasn't exited, collect some information + if process.GetState() != lldb.eStateExited: + self.runCmd("thread list") + self.runCmd("process status") + + # At this point, the inferior process should have exited. + self.assertEqual( + process.GetState(), lldb.eStateExited, + PROCESS_EXITED) diff --git a/lldb/test/API/functionalities/mixed_debugger/arkts/main.c b/lldb/test/API/functionalities/mixed_debugger/arkts/main.c new file mode 100644 index 0000000000000000000000000000000000000000..ae2d25530c6e099b46975a7c4150740718c6fcdf --- /dev/null +++ b/lldb/test/API/functionalities/mixed_debugger/arkts/main.c @@ -0,0 +1,27 @@ +// Copyright (C) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +static int var = 5; +const char *bt = "This is a ArkTS backtrace"; + +const char *GetJsBacktrace() { + return bt; +} + +int main () +{ + printf ("%p is %d\n", &var, var); // break on this line + return ++var; +} diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/split-dwarf-multiple-cu.ll b/lldb/test/Shell/SymbolFile/DWARF/x86/split-dwarf-multiple-cu.ll index 9c2348750cfb32a78b399fc6c5242ddf074feec7..0cc8b1f1b8e85db8acceadbd7a990dbf385d87ad 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/split-dwarf-multiple-cu.ll +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/split-dwarf-multiple-cu.ll @@ -1,7 +1,7 @@ ; Check handling of dwo files with multiple compile units. Right now this is not ; supported, but it should not cause us to crash or misbehave either... -; RUN: llc %s -filetype=obj -o %t.o --split-dwarf-file=%t.o +; RUN: llc %s -filetype=obj -o %t.o --split-dwarf-file=%t.o -split-dwarf-cross-cu-references ; RUN: %lldb %t.o -o "image lookup -s x1 -v" -o "image lookup -s x2 -v" -b | FileCheck %s ; CHECK: image lookup -s x1 diff --git a/llvm-build/MakeLiblzma b/llvm-build/MakeLiblzma index 681fa4e1304f3fd528d85639633c7e5fa1e2f5b4..5a98a98e4f1f2a0c1ca710a28529338cb5032930 100644 --- a/llvm-build/MakeLiblzma +++ b/llvm-build/MakeLiblzma @@ -13,54 +13,93 @@ SYSROOT := INSTALL_DIR := +BUILD_DIR := TARGET_TRIPLE := CC := -SRCS := 7zAlloc.c 7zArcIn.c 7zBuf2.c 7zBuf.c 7zCrc.c 7zCrcOpt.c 7zDec.c 7zFile.c 7zStream.c Aes.c AesOpt.c Alloc.c Bcj2.c Bra86.c Bra.c BraIA64.c CpuArch.c Delta.c LzFind.c Lzma2Dec.c Lzma2Enc.c Lzma86Dec.c Lzma86Enc.c LzmaDec.c LzmaEnc.c LzmaLib.c Ppmd7.c Ppmd7Dec.c Ppmd7Enc.c Sha256.c Sha256Opt.c Sort.c Xz.c XzCrc64.c XzCrc64Opt.c XzDec.c XzEnc.c XzIn.c MtDec.c MtCoder.c LzFindMt.c LzFindOpt.c Threads.c +AR := +SRCS := 7zAlloc.c 7zArcIn.c 7zBuf2.c 7zBuf.c 7zCrc.c 7zCrcOpt.c 7zDec.c 7zFile.c 7zStream.c Alloc.c Bcj2.c Bra86.c Bra.c BraIA64.c CpuArch.c Delta.c LzFind.c Lzma2Dec.c Lzma2Enc.c Lzma86Dec.c Lzma86Enc.c LzmaDec.c LzmaEnc.c LzmaLib.c Ppmd7.c Ppmd7Dec.c Ppmd7Enc.c Sha256.c Sha256Opt.c Sort.c Xz.c XzCrc64.c XzCrc64Opt.c XzDec.c XzEnc.c XzIn.c MtDec.c MtCoder.c LzFindMt.c LzFindOpt.c Threads.c + SRC_PREFIX := LIB_VERSION := +C_CFLAGS_COMMON := -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC -fstack-protector-strong +C_CFLAGS_OHOS := -D_IS_TRY_USE_HW_SHA=0 -DZ7_AFFINITY_DISABLE -Wno-implicit-function-declaration +IS_STATIC := +ifeq ($(IS_STATIC), True) + LDFLAGS_IS_STATIC := -static + TARGET_NAME := liblzma.a +else + LDFLAGS_IS_STATIC := -shared + TARGET_NAME := liblzma.so +endif + +$(info TARGET TRIPLE:$(TARGET_TRIPLE)) ifeq ($(TARGET_TRIPLE),linux-x86_64) -CFLAGS := --target=x86_64-unknown-linux-gnu -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC -fstack-protector-strong +CFLAGS := --target=x86_64-unknown-linux-gnu $(C_CFLAGS_COMMON) LDFLAGS := -shared -fuse-ld=lld -Wl,-z,relro,-z,now -Wl,-z,noexecstack TARGET := liblzma.so else ifeq ($(TARGET_TRIPLE),windows-x86_64) -CFLAGS := --target=x86_64-pc-windows-gnu --sysroot=$(SYSROOT) -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC -fstack-protector-strong +CFLAGS := --target=x86_64-pc-windows-gnu --sysroot=$(SYSROOT) $(C_CFLAGS_COMMON) LDFLAGS := -shared -fuse-ld=lld --rtlib=compiler-rt -Wl,--out-implib=liblzma.dll.a TARGET := liblzma.dll TARGET_A := liblzma.dll.a else ifeq ($(findstring darwin,$(TARGET_TRIPLE)),darwin) SDKROOT := $(shell xcrun --sdk macosx --show-sdk-path) -CFLAGS := -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC -current_version $(LIB_VERSION) -compatibility_version $(LIB_VERSION) -fstack-protector-strong +CFLAGS := $(C_CFLAGS_COMMON) -current_version $(LIB_VERSION) -compatibility_version $(LIB_VERSION) LDFLAGS := -dynamiclib -fuse-ld=lld -Wl,-syslibroot,$(SDKROOT) -install_name @rpath/liblzma.$(LIB_VERSION).dylib TARGET := liblzma.$(LIB_VERSION).dylib else +ifeq ($(TARGET_TRIPLE),arm-linux-ohos) +CFLAGS := --target=arm-linux-ohos -march=armv7-a -mfloat-abi=softfp --sysroot=$(SYSROOT) $(C_CFLAGS_COMMON) $(C_CFLAGS_OHOS) -I$(SYSROOT)/$(TARGET_TRIPLE)/usr/include +LDFLAGS := $(LDFLAGS_IS_STATIC) -fuse-ld=lld -Wl,-z,relro,-z,now -Wl,-z,noexecstack --sysroot=$(SYSROOT) -L$(SYSROOT)/$(TARGET_TRIPLE)/usr/lib -lc --rtlib=compiler-rt -lpthread -lunwind +TARGET := $(TARGET_NAME) +else +ifeq ($(TARGET_TRIPLE),aarch64-linux-ohos) +CFLAGS := --target=aarch64-linux-ohos --sysroot=$(SYSROOT) $(C_CFLAGS_COMMON) $(C_CFLAGS_OHOS) -I$(SYSROOT)/$(TARGET_TRIPLE)/usr/include +LDFLAGS := $(LDFLAGS_IS_STATIC) -fuse-ld=lld -Wl,-z,relro,-z,now -Wl,-z,noexecstack --sysroot=$(SYSROOT) -L$(SYSROOT)/$(TARGET_TRIPLE)/usr/lib -lc --rtlib=compiler-rt -lpthread -lunwind +TARGET := $(TARGET_NAME) +else $(warning *** warning: TARGET_TRIPLE $(TARGET_TRIPLE) has not been set in rights) endif endif endif +endif +endif lzma_header_install: @echo "begin header install" mkdir -p $(INSTALL_DIR)/include cp -rf $(SRC_PREFIX)* $(INSTALL_DIR)/include +ifeq ($(IS_STATIC), True) +# Compile the source file as .o +OBJECTS := $(addprefix $(BUILD_DIR)/, $(SRCS:.c=.o)) +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) +$(BUILD_DIR)/%.o: $(SRC_PREFIX)/%.c | $(BUILD_DIR) + $(CC) $(CFLAGS) -c $< -o $@ +# Link. o as a static library +$(TARGET): $(OBJECTS) lzma_header_install + $(AR) rc $(TARGET) $(OBJECTS) +else $(TARGET): lzma_header_install $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(addprefix $(SRC_PREFIX), $(SRCS)) +endif .PHONY: clean clean: - rm -f $(TARGET) $(SRC_PREFIX)*.o + rm -f $(TARGET) $(SRC_PREFIX)*.o $(BUILD_DIR)/*.o .PHONY:install install: $(TARGET) @echo "begin install" - mkdir -p $(INSTALL_DIR)/lib/$(TARGET_TRIPLE) - mv $(TARGET) $(INSTALL_DIR)/lib/$(TARGET_TRIPLE) + mkdir -p $(INSTALL_DIR)/lib + mv $(TARGET) $(INSTALL_DIR)/lib ifeq ($(TARGET_TRIPLE),windows-x86_64) - mv $(TARGET_A) $(INSTALL_DIR)/lib/$(TARGET_TRIPLE) + mv $(TARGET_A) $(INSTALL_DIR)/lib endif @echo "install success!" diff --git a/llvm-build/README.md b/llvm-build/README.md index f0b202f79bd8e427245ff1e1583c525e8a854e4f..a1dfc1f1e4dfb09d7fb36f68f96d57b5ecccc07b 100644 --- a/llvm-build/README.md +++ b/llvm-build/README.md @@ -20,7 +20,7 @@ MacOS X >= 10.15.4 ubuntu ``` -sudo apt-get install build-essential swig python3-dev libedit-dev libncurses5-dev binutils-dev gcc-multilib abigail-tools elfutils +sudo apt-get install build-essential swig python3-dev libedit-dev libncurses5-dev binutils-dev gcc-multilib abigail-tools elfutils pkg-config autoconf autoconf-archive ``` mac ``` diff --git a/llvm-build/build.py b/llvm-build/build.py index 5b01a6600bc560c8d03f2730c103e078de787f25..c8d3af780e4fb93342c100e72b04ccbfb77b9b39 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -643,6 +643,8 @@ class BuildUtils(object): defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' defines['LIBUNWIND_USE_FRAME_HEADER_CACHE'] = 'ON' + defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'OFF' + defines['LIBOMP_INSTALL_ALIASES'] = 'False' return defines def get_python_dir(self): @@ -684,6 +686,12 @@ class BuildUtils(object): prog = re.compile(r'#define MY_VERSION_NUMBERS "(.*?)"') return self.get_version(lzma_version_file, prog) + def merge_install_dir(self, name, platform_triple, *args): + return self.merge_out_path('third_party', name, 'install', platform_triple, *args) + + def merge_build_dir(self, name, platform_triple, *args): + return self.merge_out_path('third_party', name, 'build', platform_triple, *args) + def merge_ncurses_install_dir(self, platform_triple, *args): return self.merge_out_path('third_party', 'ncurses', 'install', platform_triple, *args) @@ -896,7 +904,7 @@ class LlvmCore(BuildUtils): llvm_defines['PANEL_LIBRARIES'] = ncurses_libs if self.build_config.enable_lzma_7zip: - llvm_defines['LIBLZMA_LIBRARIES'] = self.merge_out_path('lzma', 'lib', self.use_platform(), 'liblzma.so') + llvm_defines['LIBLZMA_LIBRARIES'] = self.merge_install_dir('lzma', self.use_platform(), 'lib', 'liblzma.so') if self.build_config.build_libedit: llvm_defines['LibEdit_LIBRARIES'] = \ @@ -953,7 +961,7 @@ class LlvmCore(BuildUtils): if self.build_config.enable_lzma_7zip: llvm_defines['LLDB_ENABLE_LZMA'] = 'ON' llvm_defines['LLDB_ENABLE_LZMA_7ZIP'] = 'ON' - llvm_defines['LIBLZMA_INCLUDE_DIRS'] = self.merge_out_path('lzma', 'include') + llvm_defines['LIBLZMA_INCLUDE_DIRS'] = self.merge_install_dir('lzma', self.use_platform(), 'include') if self.build_config.build_libedit: llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'ON' @@ -1150,8 +1158,8 @@ class LlvmCore(BuildUtils): if self.build_config.enable_lzma_7zip: windows_defines['LLDB_ENABLE_LZMA'] = 'ON' windows_defines['LLDB_ENABLE_LZMA_7ZIP'] = 'ON' - windows_defines['LIBLZMA_INCLUDE_DIRS'] = self.merge_out_path('lzma', 'include') - windows_defines['LIBLZMA_LIBRARIES'] = self.merge_out_path('lzma', 'lib', 'windows-x86_64', 'liblzma.dll.a') + windows_defines['LIBLZMA_INCLUDE_DIRS'] = self.merge_install_dir('lzma', 'windows-x86_64', 'include') + windows_defines['LIBLZMA_LIBRARIES'] = self.merge_install_dir('lzma', 'windows-x86_64', 'lib', 'liblzma.dll.a') def llvm_compile_windows_flags(self, windows_defines, @@ -1570,6 +1578,7 @@ class LlvmLibs(BuildUtils): self.open_ohos_triple('aarch64'), self.open_ohos_triple('riscv64'), self.open_ohos_triple('mipsel'), self.open_ohos_triple('x86_64'), self.open_ohos_triple('loongarch64')] + omp_list = [self.open_ohos_triple("aarch64"), self.open_ohos_triple("arm"), self.open_ohos_triple('x86_64')] libcxx_ndk_install = self.merge_out_path('libcxx-ndk') self.check_create_dir(libcxx_ndk_install) @@ -1591,9 +1600,11 @@ class LlvmLibs(BuildUtils): self.build_lldb_tools(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines) seen_arch_list.append(llvm_triple) + if llvm_triple in omp_list: + self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, 'TRUE') + self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, 'FALSE') continue - self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) self.build_libz(arch, llvm_triple, cflags, ldflags, defines) if self.build_config.need_lldb_tools and has_lldb_tools and llvm_triple not in seen_arch_list: self.build_lldb_tools(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines) @@ -1784,6 +1795,31 @@ class LlvmLibs(BuildUtils): target=None, install=True) + if arch == 'aarch64' and not first_time: + build_target = [] + install_target = [] + crt_extra_flags.append('-mbranch-protection=bti') + build_target = ['clang_rt.crtbegin-aarch64', 'clang_rt.crtend-aarch64'] + install_target = ['install-clang_rt.crtend-aarch64', 'install-clang_rt.crtbegin-aarch64'] + crt_flags = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_C_FLAGS'] = crt_flags + crt_defines['CMAKE_ASM_FLAGS'] = crt_flags + crt_defines['CMAKE_CXX_FLAGS'] = crt_flags + + self.invoke_cmake(crt_cmake_path, + crt_path, + crt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=crt_path, + env=dict(self.build_config.ORIG_ENV), + target=build_target, + install=False) + self.invoke_ninja(out_path=crt_path, + env=dict(self.build_config.ORIG_ENV), + target=install_target, + install=False) + def build_libomp(self, llvm_install, arch, @@ -1791,8 +1827,8 @@ class LlvmLibs(BuildUtils): cflags, ldflags, multilib_suffix, - defines): - + defines, + enable_shared): self.logger().info('Building libomp for %s', arch) libomp_path = self.merge_out_path('lib', 'libomp-%s' % llvm_triple) @@ -1813,7 +1849,7 @@ class LlvmLibs(BuildUtils): libomp_defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'FALSE' libomp_defines['OPENMP_LIBDIR_SUFFIX'] = os.path.join(os.sep, llvm_triple, multilib_suffix) - libomp_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + libomp_defines['LIBOMP_ENABLE_SHARED'] = enable_shared libomp_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW' libomp_defines['CMAKE_INSTALL_PREFIX'] = llvm_install libomp_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' @@ -1823,13 +1859,17 @@ class LlvmLibs(BuildUtils): libomp_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' libomp_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'openmp') - self.rm_cmake_cache(libomp_path) + + if enable_shared == "TRUE": + libomp_path = os.path.join(libomp_path, "shared") + else: + libomp_path = os.path.join(libomp_path, "static") + self.rm_cmake_cache(libomp_path) self.invoke_cmake(libomp_cmake_path, libomp_path, libomp_defines, env=dict(self.build_config.ORIG_ENV)) - self.invoke_ninja(out_path=libomp_path, env=dict(self.build_config.ORIG_ENV), target=None, @@ -1964,6 +2004,13 @@ class LlvmLibs(BuildUtils): lldb_defines['LIBXML2_INCLUDE_DIR'] = self.merge_libxml2_install_dir(llvm_triple, 'include', 'libxml2') lldb_defines['LIBXML2_LIBRARY'] = self.merge_libxml2_install_dir(llvm_triple, 'lib', 'libxml2.a') + if self.build_config.enable_lzma_7zip: + self.build_lzma(None, llvm_install, llvm_triple, True) + lldb_defines['LLDB_ENABLE_LZMA'] = 'ON' + lldb_defines['LLDB_ENABLE_LZMA_7ZIP'] = 'ON' + lldb_defines['LIBLZMA_INCLUDE_DIRS'] = self.merge_install_dir('lzma', llvm_triple, 'include') + lldb_defines['LIBLZMA_LIBRARIES'] = self.merge_install_dir('lzma', llvm_triple, 'lib', 'liblzma.a') + if self.build_config.lldb_timeout: lldb_defines['LLDB_ENABLE_TIMEOUT'] = 'True' @@ -2059,40 +2106,54 @@ class LlvmLibs(BuildUtils): self.llvm_package.copy_ncurses_to_llvm(platform_triple, llvm_make) self.llvm_package.copy_ncurses_to_llvm(platform_triple, llvm_install) - def build_lzma(self, llvm_make, llvm_install): + def build_lzma(self, llvm_make, llvm_install, platform_triple, static = False): self.logger().info('Building lzma') target_triple = self.use_platform() - liblzma_build_path = self.merge_out_path('lzma') - llvm_clang_prebuilts = os.path.abspath(os.path.join(self.buildtools_path, 'clang', 'ohos', self.use_platform(), + liblzma_install_path = self.merge_install_dir('lzma', platform_triple) + liblzma_build_path = self.merge_build_dir('lzma', platform_triple) + asm_source_dir = os.path.join(self.build_config.REPOROOT_DIR, 'third_party', 'lzma', 'Asm') + sysroot = "" + asm_arc_dir = "" + ar = "" + if not platform_triple.endswith("ohos"): + if platform_triple.startswith("windows"): + llvm_clang_prebuilts = self.merge_out_path('llvm-install', 'bin', 'clang') + sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + target_triple = platform_triple + else: + llvm_clang_prebuilts = os.path.abspath(os.path.join(self.buildtools_path, 'clang', 'ohos', self.use_platform(), 'clang-%s' % self.build_config.CLANG_VERSION, 'bin', 'clang')) + else: + llvm_clang_prebuilts = self.merge_out_path('llvm-install', 'bin', 'clang') + sysroot = self.merge_out_path("sysroot") + ar = self.merge_out_path('llvm-install', 'bin', 'llvm-ar') + target_triple = platform_triple + if platform_triple.startswith("aarch64"): + asm_arc_dir = os.path.abspath(os.path.join(asm_source_dir, 'arm64')) + if platform_triple.startswith("arm"): + asm_arc_dir = os.path.abspath(os.path.join(asm_source_dir, 'arm')) + src_dir = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party', 'lzma', 'C')) cmd = [ 'make', 'install', 'CC=%s' % llvm_clang_prebuilts, 'SRC_PREFIX=%s/' % src_dir, + 'ASM_PREFIX=%s/' % asm_arc_dir, + 'SYSROOT=%s' % sysroot, + 'AR=%s' % ar, 'TARGET_TRIPLE=%s' % target_triple, - 'INSTALL_DIR=%s' % liblzma_build_path, + 'INSTALL_DIR=%s' % liblzma_install_path, + 'BUILD_DIR=%s' % liblzma_build_path, 'LIB_VERSION=%s' % self.build_config.LZMA_VERSION, + 'IS_STATIC=%s' % static, '-f', 'MakeLiblzma'] os.chdir(self.build_config.LLVM_BUILD_DIR) self.check_call(cmd) - if self.host_is_darwin(): - shlib_ext = f'.{self.build_config.LZMA_VERSION}.dylib' - if self.host_is_linux(): - shlib_ext = '.so' - lzma_file = os.path.join(liblzma_build_path, 'lib', target_triple, 'liblzma' + shlib_ext) - - self.logger().info('Copy lzma to llvm make dir is %s', llvm_make) - lib_make_path = os.path.join(llvm_make, 'lib') - self.check_create_dir(lib_make_path) - self.check_copy_file(lzma_file, lib_make_path + '/liblzma' + shlib_ext) - - self.logger().info('Copy lzma to llvm install dir is %s', llvm_install) - lib_dst_path = os.path.join(llvm_install, 'lib') - self.check_create_dir(lib_dst_path) - self.check_copy_file(lzma_file, lib_dst_path + '/liblzma' + shlib_ext) + if not static: + self.llvm_package.copy_lzma_to_llvm(platform_triple, llvm_make) + self.llvm_package.copy_lzma_to_llvm(platform_triple, llvm_install) def build_libedit(self, llvm_make, llvm_install, platform_triple, static = False): self.logger().info('Building libedit') @@ -2429,7 +2490,7 @@ class LlvmPackage(BuildUtils): elif bin_filename not in script_bins and self.build_config.strip: if self.host_is_darwin(): self.check_call(['strip', '-x', binary]) - elif host.startswith('ohos'): + elif host.startswith('ohos') or host.endswith('aarch64'): self.check_call(['eu-strip', binary]) else: self.check_call(['strip', binary]) @@ -2654,7 +2715,7 @@ class LlvmPackage(BuildUtils): if self.build_config.enable_lzma_7zip: windows_additional_bin_files += ['liblzma%s' % shlib_ext] bin_root = os.path.join(install_dir, 'bin') - prebuild_dir = self.merge_out_path('lzma', 'lib', 'windows-x86_64', 'liblzma.dll') + prebuild_dir = self.merge_install_dir('lzma', 'windows-x86_64', 'lib', 'liblzma.dll') shutil.copyfile(prebuild_dir, os.path.join(bin_root, 'liblzma.dll')) new_necessary_bin_files = list(set(necessary_bin_files) - set(windows_forbidden_list_bin_files)) @@ -2825,6 +2886,25 @@ class LlvmPackage(BuildUtils): self.check_copy_file(libxml2_src, lib_dst_path) + def copy_lzma_to_llvm(self, platform_triple, install_dir): + self.logger().info('copy_lzma_to_llvm install_dir is %s', install_dir) + + if self.host_is_darwin(): + shlib_ext = [f'.{self.build_config.LZMA_VERSION}.dylib'] + if self.host_is_linux(): + shlib_ext = ['.so'] + if platform_triple.startswith("windows"): + shlib_ext = ['.dll'] + lzma_file = [self.merge_install_dir('lzma', platform_triple, 'lib', + f'liblzma{ext}') for ext in shlib_ext] + + lib_dst_path = os.path.join(install_dir, 'lib') + if not os.path.exists(lib_dst_path): + os.makedirs(lib_dst_path) + + for file in lzma_file: + self.check_copy_file(file, lib_dst_path) + # Packing Operation. def package_operation(self, build_dir, host): @@ -2977,7 +3057,7 @@ def main(): if build_config.LZMA_VERSION is None: raise Exception('Lzma version information not found, please check if the 7zVersion.h file exists') if build_config.enable_lzma_7zip: - llvm_libs.build_lzma(llvm_make, llvm_install) + llvm_libs.build_lzma(llvm_make, llvm_install, build_utils.use_platform()) build_config.LIBEDIT_VERSION = build_utils.get_libedit_version() if build_config.LIBEDIT_VERSION is None: @@ -3097,22 +3177,7 @@ def main(): if build_config.enable_lzma_7zip: build_utils.logger().info('build windows lzma') target_triple = 'windows-x86_64' - build_dir = build_utils.merge_out_path('lzma') - build_utils.check_create_dir(build_dir) - clang_path = build_utils.merge_out_path('llvm-install', 'bin', 'clang') - src_dir = os.path.abspath(os.path.join(build_config.REPOROOT_DIR, 'third_party', 'lzma', 'C')) - windows_sysroot = build_utils.merge_out_path('mingw', build_config.MINGW_TRIPLE) - cmd = [ 'make', - 'install', - 'CC=%s' % clang_path, - 'SRC_PREFIX=%s/' % src_dir, - 'SYSROOT=%s' % windows_sysroot, - 'TARGET_TRIPLE=%s' % target_triple, - 'INSTALL_DIR=%s' % build_dir, - '-f', - 'MakeLiblzma'] - os.chdir(build_config.LLVM_BUILD_DIR) - build_utils.check_call(cmd) + llvm_libs.build_lzma(build_utils.merge_out_path(target_triple), windows64_install, target_triple) llvm_core.llvm_compile_for_windows(build_config.TARGETS, build_config.enable_assertions, diff --git a/llvm-build/checksec/.gitignore b/llvm-build/checksec/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..18be8e5a5c38042a91fa94e953312825bffcfc0f --- /dev/null +++ b/llvm-build/checksec/.gitignore @@ -0,0 +1,6 @@ +*-log +check.txt +failed_list.txt +checksec/ +checksec.sh/ + diff --git a/llvm-build/checksec/README.md b/llvm-build/checksec/README.md new file mode 100644 index 0000000000000000000000000000000000000000..485a3a92b926091fbf88dcb6753567671a884611 --- /dev/null +++ b/llvm-build/checksec/README.md @@ -0,0 +1,47 @@ +## Overview +This Readme Briefly describes the usage of run_checksec.sh to check security compilation options for binary build artifacts. + +## Usage + +Before using this script, you may need to clone the [checksec](https://github.com/slimm609/checksec) repository to the current directory (`llvm-build/checksec`) yourself. And If you previously executed run_checksec.sh and report the error `Need to look up README to use the script`, you should take the same actions. + +Then the directory structure should be as follows: +```txt +checksec (The current directory.) +├── check.py +├── checksec (the checksec repository you cloned) +│ ├── checksec (the checksec scrpt to exec in open-source checksec repository) +│ ├── ... +├── llvmsec-log +│ ├── ... +├── README.md +├── run_checksec.sh (* use it to check our binary build artifacts) +└── templates + ├── ... +``` + +Now run `run_checksec.sh` to check security compilation options for binary build artifacts. + +Use '-h/--help' to print the usage of 'run_checksec.sh': + +```shell +$ ./run_checksec.sh -h +Usage: ./run_checksec.sh [-s][-c check_dir] [-o ./llvmts-log/checksec] [OPTION] + +Options are: + -c/--check_dir check_dir: Path to the binary file that you want to check using checksec. + -o/--output_path output_path: Path to store the results of the binary security compilation option checks. + -h/--help print usage of run_checksec.sh +``` + +You can set the check directory using '-c/--check_dir' option and set the report output directory using '-o/--output_path' option: + +`./run_checksec.sh -c=~/llvm_checksec/out/llvm-install/bin -o llvmts-log/checksec` + +default running : `./run_checksec.sh` + +This will default to checking the binary compilation products under `llvm_build/../../../out/llvm-install` and output the report in `llvm-build/checksec/llvmsec-log/`. + +Finally, a visual HTML report like this will be generated through templates: + +![HTML report](./attachment/image.png) diff --git a/llvm-build/checksec/attachment/image.png b/llvm-build/checksec/attachment/image.png new file mode 100644 index 0000000000000000000000000000000000000000..e35c96053bda8c16b9386fdcc98aceccffe4427a Binary files /dev/null and b/llvm-build/checksec/attachment/image.png differ diff --git a/llvm-build/checksec/check.py b/llvm-build/checksec/check.py new file mode 100644 index 0000000000000000000000000000000000000000..a90cb53dbd5cf1cb0bba877d8c3ac5e073a47430 --- /dev/null +++ b/llvm-build/checksec/check.py @@ -0,0 +1,535 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 Huawei Device Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import time +import datetime +import argparse +import jinja2 +import subprocess +from typing import List, Dict, Union + +# Constants for check statuses +CHECK_TRUE = 'true' +CHECK_FALSE = 'false' +CHECK_PASS = 'passed' +CHECK_FAILED = 'failed' +CHECK_ITEM_NUM = 11 + +class HtmlTitle: + """Class representing summary data for the report.""" + + _start_time = 0 + _end_time = 0 + _execution_time = 0 + _total_file_num = 0 + _file_size_sum = 0 + _check_file_list_num = 0 + +def is_executable_or_library(file_name: str) -> bool: + """ + Check if the given file is an executable or library file. + + :param file_name: The name of the file to check + :return: True if the file is executable or a library, False otherwise + """ + # Check if the file exists first. + if not os.path.isfile(file_name): + return False + # Filter by file extension. + # valid_extensions = ('.out', '.bin', '.elf', '.so', '.a') + # if file_name.endswith(valid_extensions) or os.access(file_name, os.X_OK): + # return True + + # Use the file command to determine the file type. + try: + file_type = subprocess.check_output(['file', '--mime-type', file_name]).decode('utf-8').strip() + # Check if the file is an executable file, shared object file, or library file. + if 'executable' in file_type or 'shared object' in file_type or 'library' in file_type: + return True + except subprocess.CalledProcessError: + pass + + return False + +class GenerateReport: + """Class for generating HTML and JSON reports from checksec results.""" + + @staticmethod + def _generate_failed_files_html_report(output_path: str, failed_file_list: List[Dict]): + """ + Generate an HTML report for failed files. + + Args: + output_path (str): Directory where the HTML file will be saved. + failed_file_list (list): List of dictionaries containing failed file details. + """ + env = jinja2.Environment(loader = jinja2.FileSystemLoader('./templates')) + template = env.get_template('failed_files_template.html') + data = { + 'check_file_list' : failed_file_list + } + document = template.render(data) + file_path=os.path.join(output_path, 'failed files list.html') + with open(file_path, 'w', encoding='utf-8') as failed_file: + failed_file.write(document) + + @staticmethod + def _generate_total_files_html_report(output_path: str, total_file_info: List[Dict]): + """ + Generate an HTML report for all scanned files. + + Args: + output_path (str): Directory where the HTML file will be saved. + total_file_info (list): List of all files and their check details. + """ + env = jinja2.Environment(loader = jinja2.FileSystemLoader('./templates')) + template = env.get_template('total_files_template.html') + data = { + 'total_file_info' : total_file_info, + } + document = template.render(data) + file_path = os.path.join(output_path, 'total file list.html') + with open(file_path, 'w', encoding='utf-8') as total_file: + total_file.write(document) + + @staticmethod + def _generate_summary_html_report(output_path: str, check_items: List['CheckItemData'], summary_data: 'HtmlTitle', + total_file_info: List[Dict]): + """ + Generate a summary HTML report. + + Args: + output_path (str): Directory where the HTML file will be saved. + check_items (list): List of check items with results. + summary_data (HtmlTitle): Summary data of the scan. + total_file_info (list): List of all files and their check details. + """ + env = jinja2.Environment(loader = jinja2.FileSystemLoader('./templates')) + template = env.get_template('index_files_template.html') + data = { + 'summary_data' : summary_data, + 'total_file_info' : total_file_info, + 'check_items' : check_items + } + document = template.render(data) + file_path = os.path.join(output_path, 'Index.html') + with open(file_path, 'w', encoding='utf-8') as index_html_file: + index_html_file.write(document) + + @staticmethod + def _generate_failed_files_json_report(output_path: str, failed_file_list: List[Dict]): + """ + Generate a JSON report for failed files. + + Args: + output_path (str): Directory where the JSON file will be saved. + failed_file_list (list): List of failed files with details. + """ + data = { + 'check_file_list' : failed_file_list + } + json_str = json.dumps(data,indent=1) + file_path = os.path.join(output_path, 'check_file_list.json') + with open(file_path, 'w' ,encoding='utf-8') as json_file: + json_file.write(json_str) + + @staticmethod + def _generate_total_files_json_report(output_path: str, total_file_info: List[Dict]): + """ + Generate a JSON report for all scanned files. + + Args: + output_path (str): Directory where the JSON file will be saved. + total_file_info (list): List of all files and their check details. + """ + data = { + 'total_file_info' : total_file_info + } + json_str =json.dumps(data,indent=1) + file_path = os.path.join(output_path, 'total_file_list.json') + with open(file_path, 'w' ,encoding ='utf-8') as json_file: + json_file.write(json_str) + + @staticmethod + def _generate_summary_json_report(output_path: str, check_items: List['CheckItemData'], summary_data: 'HtmlTitle', + total_file_info: List[Dict]): + """ + Generate a summary JSON report. + + Args: + output_path (str): Directory where the JSON file will be saved. + check_items (list): List of check items with results. + summary_data (HtmlTitle): Summary data of the scan. + total_file_info (list): List of all files and their check details. + """ + summary_data_dict = summary_data.__dict__ + check_items_dict = {} + for i in check_items: + check_items_dict[i._name] = i.__dict__ + data = { + 'summary_data' : summary_data_dict, + 'total_file_info' : total_file_info, + 'check_items' : check_items_dict, + } + json_str = json.dumps(data ,indent=1) + file_path = os.path.join(output_path, 'Index.json') + with open(file_path, 'w',encoding='utf-8') as json_file: + json_file.write(json_str) + +class CheckItemData: + """Class representing data for a single security check item.""" + + def __init__(self, name: str, do_check: str = CHECK_FALSE, check_flag: Union[str, None] = None): + """ + Initialize a check item. + + Args: + name (str): Name of the check item. + do_check (str): Whether this check is enabled. Defaults to CHECK_FALSE. + check_flag (str | None): Expected value to compare during the check. + """ + self._name = name + self._do_check = do_check + self._check_flag = check_flag + self._passed_list = [] + self._failed_list = [] + self._passed_num = 0 + self._failed_num = 0 + +class CheckData: + """Class for handling security checks and generating check data.""" + + def __init__(self) -> None: + """ + Initialize the CheckData object with default check items. + """ + self._relro_check = CheckItemData('relro', CHECK_TRUE, 'full') + self._nx_check = CheckItemData('nx', CHECK_TRUE, 'yes') + self._rpath_check = CheckItemData('rpath', CHECK_TRUE, 'no') + self._canary_check = CheckItemData('canary') + self._pie_check = CheckItemData('pie') + self._fortify_check = CheckItemData('fortify') + self._symbols_check = CheckItemData('symbols') + self._clangcfi_check = CheckItemData('clangcfi') + self._clang_safestack_check = CheckItemData('safestack') + self._fortified_check = CheckItemData('fortified') + self._fortifiable_check = CheckItemData('fortify-able') + + def _check_security(self, check_file_path: str, check_dir: str, check_items: List[CheckItemData], + summary_data: 'HtmlTitle', file_name_list: List[str], total_file_info: List[Dict]): + """ + Perform security checks on files in a directory. + + Args: + check_file_path (str): Path to the JSON file storing file information. + check_dir (str): Directory containing the files to be checked. + check_items (list): List of CheckItemData objects representing check configurations. + summary_data (HtmlTitle): Summary data object to store aggregate information. + file_name_list (list): List to store the names of checked files. + total_file_info (list): List to store detailed information about all files. + """ + check_path=check_dir + if not os.path.exists(check_path): + print("check error: check file is not exist") + exit() + checksec_statement = './checksec/checksec --dir={0} --extended --output=json'.format(check_path) + print(checksec_statement) + + checksec_output = json.loads(os.popen(checksec_statement).read()) + self.__generate_summary_data(checksec_output, check_items, summary_data, file_name_list, total_file_info) + + def __generate_summary_data(self, checksec_output: Dict, check_items: List[CheckItemData], + summary_data: 'HtmlTitle', file_name_list: List[str], total_file_info: List[Dict]): + """ + Generate summary data from checksec output. + + Args: + checksec_output (dict): Parsed JSON output from checksec. + check_items (list): List of CheckItemData objects representing check configurations. + summary_data (HtmlTitle): Summary data object to store aggregate information. + file_name_list (list): List to store the names of checked files. + total_file_info (list): List to store detailed information about all files. + """ + file_size_sum = 0 + for file_info in checksec_output.values(): + if 'name' not in file_info: + file_name = file_info.get('filename') + if not is_executable_or_library(file_name): # if the given file isn't an executable or library file, filter out + continue + file_name_list.append(''.join(list(key for key, value in checksec_output.items() if value == file_info))) + summary_data._total_file_num = len(file_name_list) + self.__generate_check_items_data(file_info, check_items) + file_info['file_single_size'] = get_file_size(os.path.getsize(file_info['filename'])) + file_info['fortify_able'] = file_info['fortify-able'] + total_file_info.append(file_info) + for check_item in check_items: + check_item._passed_num = len(check_item._passed_list) + check_item._failed_num = len(check_item._failed_list) + for file_name in file_name_list: + file_size_sum += os.path.getsize(file_name) + summary_data._file_size_sum = get_file_size(file_size_sum) + + def __generate_check_items_data(self, file_info: Dict, check_items: List[CheckItemData]): + """ + Populate check item results for a single file. + + Args: + file_info (dict): Information about a single file. + check_items (list): List of CheckItemData objects representing check configurations. + """ + for i in range(0, CHECK_ITEM_NUM): + if check_items[i]._do_check == CHECK_TRUE: + if check_items[i]._check_flag == list(file_info.values())[i]: + check_items[i]._passed_list.append(file_info['filename']) + else: + check_items[i]._failed_list.append(file_info['filename']) + else: + check_items[i]._passed_list.append(file_info['filename']) + + def _generate_failed_files_data(self, check_items: List[CheckItemData], summary_data: 'HtmlTitle', + file_name_list: List[str], failed_file_list: List[Dict]): + """ + Generate data for files that failed security checks. + + Args: + check_items (list): List of CheckItemData objects representing check configurations. + summary_data (HtmlTitle): Summary data object to store aggregate information. + file_name_list (list): List of all checked file names. + failed_file_list (list): List to store information about failed files. + """ + for file_name in file_name_list: + if not is_executable_or_library(file_name): #if the given file isn't an executable or library file, filter out + continue + file_info = {} + file_info['file_name'] = file_name + for check_item in check_items: + if file_name in check_item._failed_list: + if check_item._name == 'fortify-able': + file_info['fortifiable'] = CHECK_FAILED + else: + file_info[check_item._name] = CHECK_FAILED + else: + if check_item._name == 'fortify-able': + file_info['fortifiable'] = CHECK_PASS + else: + file_info[check_item._name] = CHECK_PASS + if CHECK_FAILED in file_info.values(): + failed_file_list.append(file_info) + summary_data._check_file_list_num = len(failed_file_list) + + +def generate_failed_list(failed_file_list: List[Dict]): + """ + Generates a text file named 'failed_list.txt' containing details of files that failed checks. + + Args: + failed_file_list (list[dict]): A list of dictionaries containing failed file information. + """ + if os.path.isfile('failed_list.txt'): + os.system('rm failed_list.txt') + if len(failed_file_list) != 0: + with open('failed_list.txt', 'w') as txt_file: + for failed_file_info in failed_file_list: + txt_file.write('{}\n'.format(failed_file_info)) + +def get_file_size(file_size: int) -> str: + """ + Format file size into human-readable format. + + Args: + file_size (int): File size in bytes. + + Returns: + str: File size as a human-readable string. + """ + if file_size < 1024: + return str(round(file_size, 2)) + 'B' + else: + file_size /= 1024 + if file_size < 1024: + return str(round(file_size, 2)) + 'K' + else: + file_size /= 1024 + if file_size < 1024: + return str(round(file_size, 2)) + 'M' + else: + file_size /= 1024 + return str(round(file_size, 2)) + 'G' + +def update_attributes(args: argparse.Namespace, check_items: List[CheckItemData]): + """ + Updates the attributes of check items based on arguments. + + Args: + args (argparse.Namespace): Parsed arguments. + check_items (list[CheckItemData]): List of security check items to update. + """ + if args.relro: + check_items[0]._do_check = CHECK_TRUE + check_items[0]._check_flag = args.relro + if args.canary: + check_items[1]._do_check = CHECK_TRUE + check_items[1]._check_flag = args.canary + if args.nx: + check_items[2]._do_check = CHECK_TRUE + check_items[2]._check_flag = args.nx + if args.pie: + check_items[3]._do_check = CHECK_TRUE + check_items[3]._check_flag = args.pie + if args.Clang_Cfi: + check_items[4]._do_check = CHECK_TRUE + check_items[4]._check_flag = args.Clang_Cfi + if args.safestack: + check_items[5]._do_check = CHECK_TRUE + check_items[5]._check_flag = args.safestack + if args.rpath: + check_items[6]._do_check = CHECK_TRUE + check_items[6]._check_flag = args.rpath + if args.symbols: + check_items[7]._do_check = CHECK_TRUE + check_items[7]._check_flag = args.symbols + if args.fortity: + check_items[8]._do_check = CHECK_TRUE + check_items[8]._check_flag = args.fortity + if args.fortified: + check_items[9]._do_check = CHECK_TRUE + check_items[9]._check_flag = args.fortified + if args.fortifiable: + check_items[10]._do_check = CHECK_TRUE + check_items[10]._check_flag = args.fortifiable + +def add_parse() -> argparse.Namespace: + """ + Parse command-line arguments. + + Returns: + argparse.Namespace: The parsed command-line arguments. + """ + parser = argparse.ArgumentParser() + parser.add_argument( + '--check_dir', + required = True, + type = str, + help='check_dir') + + parser.add_argument( + '--output_path', + required = True, + type = str, + help='output path to save the report') + + parser.add_argument( + '--relro', + type = str, + help = 'set relro expected value and compare actual value with expected value') + + parser.add_argument( + '--nx', + type = str, + help = 'set nx expected value and compare actual value with expected value') + + parser.add_argument( + '--rpath', + type = str, + help = 'set rpath expected value and compare actual value with expected value') + + parser.add_argument( + '--canary', + type = str, + help = 'set canary expected value and compare actual value with expected value') + + parser.add_argument( + '--pie', + type = str, + help = 'set pie expected value and compare actual value with expected value') + + parser.add_argument( + '--symbols', + type = str, + help = 'set symbols expected value and compare actual value with expected value') + + parser.add_argument( + '--fortity', + type = str, + help = 'set fortity expected value and compare actual value with expected value') + + parser.add_argument( + '--safestack', + type = str, + help = 'set safestack expected value and compare actual value with expected value') + + parser.add_argument( + '--Clang_Cfi', + type = str, + help = 'set Clang-Cfi expected value and compare actual value with expected value') + + parser.add_argument( + '--fortified', + type = str, + help = 'set fortified expected value and compare actual value with expected value') + + parser.add_argument( + '--fortifiable', + type = str, + help = 'set fortify-able expected value and compare actual value with expected value') + return parser.parse_args() + +def main(): + """ + Main function to execute the security check process and generate reports. + """ + start_time = time.time() + summary_data = HtmlTitle() + summary_data._start_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') + check_file_path = 'check_file_path.json' + args=add_parse() + output_path = args.output_path + + check_dir = args.check_dir + if check_dir[-1] == '/': + check_dir = check_dir[:-1] + + check_data = CheckData() + check_items = [check_data._relro_check, check_data._canary_check, check_data._nx_check, check_data._pie_check, + check_data._clangcfi_check, check_data._clang_safestack_check, check_data._rpath_check, check_data._symbols_check, + check_data._fortify_check, check_data._fortified_check, check_data._fortifiable_check] + update_attributes(args, check_items) + file_name_list = [] + failed_file_list = [] + total_file_info = [] + check_data._check_security(check_file_path, check_dir, check_items, summary_data, file_name_list, total_file_info) + check_data._generate_failed_files_data(check_items, summary_data, file_name_list, failed_file_list) + + summary_data._end_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') + end_time = time.time() + run_time = round(end_time - start_time, 2) + summary_data._execution_time = str(run_time) + 's' + if output_path[-1] != '/': + output_path = os.path.join(output_path, '') + report = GenerateReport() + report._generate_summary_html_report(output_path, check_items, summary_data, total_file_info) + report._generate_total_files_html_report(output_path, total_file_info) + report._generate_failed_files_html_report(output_path, failed_file_list) + + report._generate_summary_json_report(output_path, check_items, summary_data, total_file_info) + report._generate_total_files_json_report(output_path, total_file_info) + report._generate_failed_files_json_report(output_path, failed_file_list) + + generate_failed_list(failed_file_list) + +if __name__ == '__main__': + main() diff --git a/llvm-build/checksec/run_checksec.sh b/llvm-build/checksec/run_checksec.sh new file mode 100755 index 0000000000000000000000000000000000000000..2ecebaaef8b12a171eaaab68429fd06ff08041db --- /dev/null +++ b/llvm-build/checksec/run_checksec.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# Copyright (C) 2024 Huawei Device Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +WORK_DIR=$(dirname "$(realpath "$0")") +check_dir="" +output_path="" +while [[ $# -gt 0 ]]; do + case $1 in + # set the check directory + -c|--check_dir) + check_dir="$(realpath "$2")" + shift 2 + ;; + # set the report output directory + -o|--output_path) + output_path="$(realpath "$2")" + shift 2 + ;; + # print the usage of 'run_checksec.sh' + -h|--help) + echo "Usage: ./run_checksec.sh [-s][-c check_dir] [-o ./llvmts-log/checksec] [OPTION]" + echo + echo "Options are:" + echo " -c/--check_dir check_dir: Path to the binary file that you want to check using checksec." + echo " -o/--output_path output_path: Path to store the results of the binary security compilation option checks." + echo " -h/--help print usage of run_checksec.sh" + exit 0 + ;; + # other unsupport option + *) + echo "Illegal option $1" + exit 1 + ;; + esac +done + +# If --check_dir/-c is not provided, use the default value +default_check_dir="$(realpath "${WORK_DIR}/../../../../out/llvm-install")" # default check path +if [ -z "$check_dir" ]; then + check_dir="$default_check_dir" +fi + +TIME=$(date +%Y%m%d%H%M) +time_dir=$(date +%Y-%m-%d-%H-%M) +# If --output_path/-o is not provided, use the default value +default_output_path="${WORK_DIR}/llvmsec-log" +if [ -z "$output_path" ]; then + output_path="$default_output_path" +fi +llvmts_logdir="${output_path}/${time_dir}/" + +echo "The check path is ${check_dir}" +echo "The check result report is stored in ${llvmts_logdir}" +echo "run checksec test" +# run check.py to run ./checksec/checksec +cd ${WORK_DIR} +if [ ! -d "checksec" ]; then + echo "Need to look up README to use the script." + exit 1 +fi +mkdir -p ${llvmts_logdir} +python3 ${WORK_DIR}/check.py --check_dir ${check_dir} --output_path ${llvmts_logdir} 2>&1 | tee ${WORK_DIR}/check.txt +cp ${WORK_DIR}/templates/bootstrap.bundle.min.js ${llvmts_logdir} +cp ${WORK_DIR}/templates/jquery.min.js ${llvmts_logdir} +cp -r ${WORK_DIR}/templates/css ${llvmts_logdir} +cp -r ${WORK_DIR}/templates/fonts ${llvmts_logdir} +if (grep -q "check error" ${WORK_DIR}/check.txt); then + exit 1 +fi +if [ -f ${WORK_DIR}/failed_list.txt ];then + echo exist failed files + exit 1 +fi diff --git a/llvm-build/checksec/templates/bootstrap.bundle.min.js b/llvm-build/checksec/templates/bootstrap.bundle.min.js new file mode 100644 index 0000000000000000000000000000000000000000..7961bdaf8e0e91721bc5832cdca1df128bad1b27 --- /dev/null +++ b/llvm-build/checksec/templates/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=n(e);function o(t,e){for(var n=0;n=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};l.jQueryDetection(),i.default.fn.emulateTransitionEnd=s,i.default.event.special[l.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(i.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var u="alert",f=i.default.fn[u],d=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){i.default.removeData(this._element,"bs.alert"),this._element=null},e._getRootElement=function(t){var e=l.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=i.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=i.default.Event("close.bs.alert");return i.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(i.default(t).removeClass("show"),i.default(t).hasClass("fade")){var n=l.getTransitionDurationFromElement(t);i.default(t).one(l.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){i.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.alert");o||(o=new t(this),n.data("bs.alert",o)),"close"===e&&o[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();i.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',d._handleDismiss(new d)),i.default.fn[u]=d._jQueryInterface,i.default.fn[u].Constructor=d,i.default.fn[u].noConflict=function(){return i.default.fn[u]=f,d._jQueryInterface};var c=i.default.fn.button,h=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=i.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var r=n.querySelector(".active");r&&i.default(r).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||i.default(o).trigger("change")),o.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&i.default(this._element).toggleClass("active"))},e.dispose=function(){i.default.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var o=i.default(this),r=o.data("bs.button");r||(r=new t(this),o.data("bs.button",r)),r.shouldAvoidTriggerChange=n,"toggle"===e&&r[e]()}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();i.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target,n=e;if(i.default(e).hasClass("btn")||(e=i.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var o=e.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||h._jQueryInterface.call(i.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=i.default(t.target).closest(".btn")[0];i.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),i.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=i.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(l.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)i.default(this._element).one("slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var o=t>n?"next":"prev";this._slide(o,this._items[t])}},e.dispose=function(){i.default(this._element).off(m),i.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=a({},v,t),l.typeCheckConfig(p,t,_),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&i.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&i.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};i.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(i.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(i.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),i.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var a=(o+("prev"===t?-1:1))%this._items.length;return-1===a?this._items[this._items.length-1]:this._items[a]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=i.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:o,to:n});return i.default(this._element).trigger(r),r},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));i.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&i.default(n).addClass("active")}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(".active.carousel-item");if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,o,r,a=this,s=this._element.querySelector(".active.carousel-item"),u=this._getItemIndex(s),f=e||s&&this._getItemByDirection(t,s),d=this._getItemIndex(f),c=Boolean(this._interval);if("next"===t?(n="carousel-item-left",o="carousel-item-next",r="left"):(n="carousel-item-right",o="carousel-item-prev",r="right"),f&&i.default(f).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(f,r).isDefaultPrevented()&&s&&f){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(f),this._activeElement=f;var h=i.default.Event("slid.bs.carousel",{relatedTarget:f,direction:r,from:u,to:d});if(i.default(this._element).hasClass("slide")){i.default(f).addClass(o),l.reflow(f),i.default(s).addClass(n),i.default(f).addClass(n);var p=l.getTransitionDurationFromElement(s);i.default(s).one(l.TRANSITION_END,(function(){i.default(f).removeClass(n+" "+o).addClass("active"),i.default(s).removeClass("active "+o+" "+n),a._isSliding=!1,setTimeout((function(){return i.default(a._element).trigger(h)}),0)})).emulateTransitionEnd(p)}else i.default(s).removeClass("active"),i.default(f).addClass("active"),this._isSliding=!1,i.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.carousel"),o=a({},v,i.default(this).data());"object"==typeof e&&(o=a({},o,e));var r="string"==typeof e?e:o.slide;if(n||(n=new t(this,o),i.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof r){if("undefined"==typeof n[r])throw new TypeError('No method named "'+r+'"');n[r]()}else o.interval&&o.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=l.getSelectorFromElement(this);if(n){var o=i.default(n)[0];if(o&&i.default(o).hasClass("carousel")){var r=a({},i.default(o).data(),i.default(this).data()),s=this.getAttribute("data-slide-to");s&&(r.interval=!1),t._jQueryInterface.call(i.default(o),r),s&&i.default(o).data("bs.carousel").to(s),e.preventDefault()}}},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return v}}]),t}();i.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",y._dataApiClickHandler),i.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){i.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,o=this;if(!this._isTransitioning&&!i.default(this._element).hasClass("show")&&(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(e=null),!(e&&(n=i.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var r=i.default.Event("show.bs.collapse");if(i.default(this._element).trigger(r),!r.isDefaultPrevented()){e&&(t._jQueryInterface.call(i.default(e).not(this._selector),"hide"),n||i.default(e).data("bs.collapse",null));var a=this._getDimension();i.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[a]=0,this._triggerArray.length&&i.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(a[0].toUpperCase()+a.slice(1)),u=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(){i.default(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[a]="",o.setTransitioning(!1),i.default(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(u),this._element.style[a]=this._element[s]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&i.default(this._element).hasClass("show")){var e=i.default.Event("hide.bs.collapse");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",l.reflow(this._element),i.default(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r=0)return 1;return 0}();var k=D&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),N))}};function A(t){return t&&"[object Function]"==={}.toString.call(t)}function I(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function O(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function x(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=I(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:x(O(t))}function j(t){return t&&t.referenceNode?t.referenceNode:t}var L=D&&!(!window.MSInputMethodContext||!document.documentMode),P=D&&/MSIE 10/.test(navigator.userAgent);function F(t){return 11===t?L:10===t?P:L||P}function R(t){if(!t)return document.documentElement;for(var e=F(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===I(n,"position")?R(n):n:t?t.ownerDocument.documentElement:document.documentElement}function H(t){return null!==t.parentNode?H(t.parentNode):t}function M(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(s=(a=l).nodeName)||"HTML"!==s&&R(a.firstElementChild)!==a?R(l):l;var u=H(t);return u.host?M(u.host,e):M(t,H(e).host)}function q(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function B(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=q(e,"top"),o=q(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Q(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function W(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],F(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function U(t){var e=t.body,n=t.documentElement,i=F(10)&&getComputedStyle(n);return{height:W("Height",e,n,i),width:W("Width",e,n,i)}}var V=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Y=function(){function t(t,e){for(var n=0;n2&&void 0!==arguments[2]&&arguments[2],i=F(10),o="HTML"===e.nodeName,r=G(t),a=G(e),s=x(t),l=I(e),u=parseFloat(l.borderTopWidth),f=parseFloat(l.borderLeftWidth);n&&o&&(a.top=Math.max(a.top,0),a.left=Math.max(a.left,0));var d=K({top:r.top-a.top-u,left:r.left-a.left-f,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!i&&o){var c=parseFloat(l.marginTop),h=parseFloat(l.marginLeft);d.top-=u-c,d.bottom-=u-c,d.left-=f-h,d.right-=f-h,d.marginTop=c,d.marginLeft=h}return(i&&!n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(d=B(d,e)),d}function J(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=$(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:q(n),s=e?0:q(n,"left"),l={top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r};return K(l)}function Z(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===I(t,"position"))return!0;var n=O(t);return!!n&&Z(n)}function tt(t){if(!t||!t.parentElement||F())return document.documentElement;for(var e=t.parentElement;e&&"none"===I(e,"transform");)e=e.parentElement;return e||document.documentElement}function et(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?tt(t):M(t,j(e));if("viewport"===i)r=J(a,o);else{var s=void 0;"scrollParent"===i?"BODY"===(s=x(O(e))).nodeName&&(s=t.ownerDocument.documentElement):s="window"===i?t.ownerDocument.documentElement:i;var l=$(s,a,o);if("HTML"!==s.nodeName||Z(a))r=l;else{var u=U(t.ownerDocument),f=u.height,d=u.width;r.top+=l.top-l.marginTop,r.bottom=f+l.top,r.left+=l.left-l.marginLeft,r.right=d+l.left}}var c="number"==typeof(n=n||0);return r.left+=c?n:n.left||0,r.top+=c?n:n.top||0,r.right-=c?n:n.right||0,r.bottom-=c?n:n.bottom||0,r}function nt(t){return t.width*t.height}function it(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=et(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},l=Object.keys(s).map((function(t){return X({key:t},s[t],{area:nt(s[t])})})).sort((function(t,e){return e.area-t.area})),u=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),f=u.length>0?u[0].key:l[0].key,d=t.split("-")[1];return f+(d?"-"+d:"")}function ot(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?tt(e):M(e,j(n));return $(n,o,i)}function rt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function at(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function st(t,e,n){n=n.split("-")[0];var i=rt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",l=r?"height":"width",u=r?"width":"height";return o[a]=e[a]+e[l]/2-i[l]/2,o[s]=n===s?e[s]-i[u]:e[at(s)],o}function lt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function ut(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=lt(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&A(n)&&(e.offsets.popper=K(e.offsets.popper),e.offsets.reference=K(e.offsets.reference),e=n(e,t))})),e}function ft(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=ot(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=it(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=st(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=ut(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function dt(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ct(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=Tt.indexOf(t),i=Tt.slice(n+1).concat(Tt.slice(0,n));return e?i.reverse():i}var St="flip",Dt="clockwise",Nt="counterclockwise";function kt(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(lt(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,u=-1!==s?[a.slice(0,s).concat([a[s].split(l)[0]]),[a[s].split(l)[1]].concat(a.slice(s+1))]:[a];return(u=u.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];if(!r)return t;if(0===a.indexOf("%")){var s=void 0;switch(a){case"%p":s=n;break;case"%":case"%r":default:s=i}return K(s)[e]/100*r}if("vh"===a||"vw"===a)return("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r;return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){_t(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var At={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,a=o.popper,s=-1!==["bottom","top"].indexOf(n),l=s?"left":"top",u=s?"width":"height",f={start:z({},l,r[l]),end:z({},l,r[l]+r[u]-a[u])};t.offsets.popper=X({},a,f[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,a=o.reference,s=i.split("-")[0],l=void 0;return l=_t(+n)?[+n,0]:kt(n,r,a,s),"left"===s?(r.top+=l[0],r.left-=l[1]):"right"===s?(r.top+=l[0],r.left+=l[1]):"top"===s?(r.left+=l[0],r.top-=l[1]):"bottom"===s&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||R(t.instance.popper);t.instance.reference===n&&(n=R(n));var i=ct("transform"),o=t.instance.popper.style,r=o.top,a=o.left,s=o[i];o.top="",o.left="",o[i]="";var l=et(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=a,o[i]=s,e.boundaries=l;var u=e.priority,f=t.offsets.popper,d={primary:function(t){var n=f[t];return f[t]l[t]&&!e.escapeWithReference&&(i=Math.min(f[n],l[t]-("right"===t?f.width:f.height))),z({},n,i)}};return u.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";f=X({},f,d[e](t))})),t.offsets.popper=f,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",l=a?"left":"top",u=a?"width":"height";return n[s]r(i[s])&&(t.offsets.popper[l]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!wt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,a=r.popper,s=r.reference,l=-1!==["left","right"].indexOf(o),u=l?"height":"width",f=l?"Top":"Left",d=f.toLowerCase(),c=l?"left":"top",h=l?"bottom":"right",p=rt(i)[u];s[h]-pa[h]&&(t.offsets.popper[d]+=s[d]+p-a[h]),t.offsets.popper=K(t.offsets.popper);var m=s[d]+s[u]/2-p/2,g=I(t.instance.popper),v=parseFloat(g["margin"+f]),_=parseFloat(g["border"+f+"Width"]),b=m-t.offsets.popper[d]-v-_;return b=Math.max(Math.min(a[u]-p,b),0),t.arrowElement=i,t.offsets.arrow=(z(n={},d,Math.round(b)),z(n,c,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(dt(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=et(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=at(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case St:a=[i,o];break;case Dt:a=Ct(i);break;case Nt:a=Ct(i,!0);break;default:a=e.behavior}return a.forEach((function(s,l){if(i!==s||a.length===l+1)return t;i=t.placement.split("-")[0],o=at(i);var u=t.offsets.popper,f=t.offsets.reference,d=Math.floor,c="left"===i&&d(u.right)>d(f.left)||"right"===i&&d(u.left)d(f.top)||"bottom"===i&&d(u.top)d(n.right),m=d(u.top)d(n.bottom),v="left"===i&&h||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&h||_&&"end"===r&&p||!_&&"start"===r&&m||!_&&"end"===r&&g),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&h||!_&&"start"===r&&g||!_&&"end"===r&&m),w=b||y;(c||v||w)&&(t.flipped=!0,(c||v)&&(i=a[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=X({},t.offsets.popper,st(t.instance.popper,t.offsets.reference,t.placement)),t=ut(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=at(e),t.offsets.popper=K(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!wt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=lt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottomn.right||e.top>n.bottom||e.right2&&void 0!==arguments[2]?arguments[2]:{};V(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=k(this.update.bind(this)),this.options=X({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(X({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=X({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return X({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&A(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Y(t,[{key:"update",value:function(){return ft.call(this)}},{key:"destroy",value:function(){return ht.call(this)}},{key:"enableEventListeners",value:function(){return gt.call(this)}},{key:"disableEventListeners",value:function(){return vt.call(this)}}]),t}();It.Utils=("undefined"!=typeof window?window:global).PopperUtils,It.placements=Et,It.Defaults=At;var Ot="dropdown",xt=i.default.fn[Ot],jt=new RegExp("38|40|27"),Lt={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Pt={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},Ft=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!i.default(this._element).hasClass("disabled")){var e=i.default(this._menu).hasClass("show");t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||i.default(this._element).hasClass("disabled")||i.default(this._menu).hasClass("show"))){var n={relatedTarget:this._element},o=i.default.Event("show.bs.dropdown",n),r=t._getParentFromElement(this._element);if(i.default(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof It)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var a=this._element;"parent"===this._config.reference?a=r:l.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&i.default(r).addClass("position-static"),this._popper=new It(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===i.default(r).closest(".navbar-nav").length&&i.default(document.body).children().on("mouseover",null,i.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),i.default(this._menu).toggleClass("show"),i.default(r).toggleClass("show").trigger(i.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!i.default(this._element).hasClass("disabled")&&i.default(this._menu).hasClass("show")){var e={relatedTarget:this._element},n=i.default.Event("hide.bs.dropdown",e),o=t._getParentFromElement(this._element);i.default(o).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),i.default(this._menu).toggleClass("show"),i.default(o).toggleClass("show").trigger(i.default.Event("hidden.bs.dropdown",e)))}},e.dispose=function(){i.default.removeData(this._element,"bs.dropdown"),i.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;i.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=a({},this.constructor.Default,i.default(this._element).data(),t),l.typeCheckConfig(Ot,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},e._getPlacement=function(){var t=i.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=i.default(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":i.default(this._menu).hasClass("dropdown-menu-right")&&(e="bottom-end"),e},e._detectNavbar=function(){return i.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),a({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),i.default(this).data("bs.dropdown",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,r=n.length;o0&&a--,40===e.which&&adocument.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=l.getTransitionDurationFromElement(this._dialog);i.default(this._element).off(l.TRANSITION_END),i.default(this._element).one(l.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),n||i.default(t._element).one(l.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}},e._showElement=function(t){var e=this,n=i.default(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),i.default(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,n&&l.reflow(this._element),i.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=i.default.Event("shown.bs.modal",{relatedTarget:t}),a=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,i.default(e._element).trigger(r)};if(n){var s=l.getTransitionDurationFromElement(this._dialog);i.default(this._dialog).one(l.TRANSITION_END,a).emulateTransitionEnd(s)}else a()},e._enforceFocus=function(){var t=this;i.default(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(e){document!==e.target&&t._element!==e.target&&0===i.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?i.default(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||i.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?i.default(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):i.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){i.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),i.default(t._element).trigger("hidden.bs.modal")}))},e._removeBackdrop=function(){this._backdrop&&(i.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=i.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),i.default(this._backdrop).appendTo(document.body),i.default(this._element).on("click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&l.reflow(this._backdrop),i.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var o=l.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(l.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){i.default(this._backdrop).removeClass("show");var r=function(){e._removeBackdrop(),t&&t()};if(i.default(this._element).hasClass("fade")){var a=l.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(l.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:Qt,popperConfig:null},Zt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},te=function(){function t(t,e){if("undefined"==typeof It)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=i.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(i.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),i.default.removeData(this.element,this.constructor.DATA_KEY),i.default(this.element).off(this.constructor.EVENT_KEY),i.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&i.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===i.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=i.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){i.default(this.element).trigger(e);var n=l.findShadowRoot(this.element),o=i.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!o)return;var r=this.getTipElement(),a=l.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&i.default(r).addClass("fade");var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,u=this._getAttachment(s);this.addAttachmentClass(u);var f=this._getContainer();i.default(r).data(this.constructor.DATA_KEY,this),i.default.contains(this.element.ownerDocument.documentElement,this.tip)||i.default(r).appendTo(f),i.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new It(this.element,r,this._getPopperConfig(u)),i.default(r).addClass("show"),i.default(r).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&i.default(document.body).children().on("mouseover",null,i.default.noop);var d=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,i.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(i.default(this.tip).hasClass("fade")){var c=l.getTransitionDurationFromElement(this.tip);i.default(this.tip).one(l.TRANSITION_END,d).emulateTransitionEnd(c)}else d()}},e.hide=function(t){var e=this,n=this.getTipElement(),o=i.default.Event(this.constructor.Event.HIDE),r=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),i.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(i.default(this.element).trigger(o),!o.isDefaultPrevented()){if(i.default(n).removeClass("show"),"ontouchstart"in document.documentElement&&i.default(document.body).children().off("mouseover",null,i.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,i.default(this.tip).hasClass("fade")){var a=l.getTransitionDurationFromElement(n);i.default(n).one(l.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(i.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),i.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Vt(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?i.default(e).parent().is(t)||t.empty().append(e):t.text(i.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return a({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:l.isElement(this.config.container)?i.default(this.config.container):i.default(document).find(this.config.container)},e._getAttachment=function(t){return $t[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)i.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;i.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},i.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=a({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),i.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=i.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Kt.indexOf(t)&&delete e[t]})),"number"==typeof(t=a({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),l.typeCheckConfig(Yt,t,this.constructor.DefaultType),t.sanitize&&(t.template=Vt(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(Xt);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(i.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.tooltip"),r="object"==typeof e&&e;if((o||!/dispose|hide/.test(e))&&(o||(o=new t(this,r),n.data("bs.tooltip",o)),"string"==typeof e)){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return Jt}},{key:"NAME",get:function(){return Yt}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Zt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Gt}}]),t}();i.default.fn[Yt]=te._jQueryInterface,i.default.fn[Yt].Constructor=te,i.default.fn[Yt].noConflict=function(){return i.default.fn[Yt]=zt,te._jQueryInterface};var ee="popover",ne=i.default.fn[ee],ie=new RegExp("(^|\\s)bs-popover\\S+","g"),oe=a({},te.Default,{placement:"right",trigger:"click",content:"",template:''}),re=a({},te.DefaultType,{content:"(string|element|function)"}),ae={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},se=function(t){var e,n;function o(){return t.apply(this,arguments)||this}n=t,(e=o).prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n;var a=o.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},a.setContent=function(){var t=i.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(ie);null!==e&&e.length>0&&t.removeClass(e.join(""))},o._jQueryInterface=function(t){return this.each((function(){var e=i.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n),i.default(this).data("bs.popover",e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},r(o,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return oe}},{key:"NAME",get:function(){return ee}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return ae}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return re}}]),o}(te);i.default.fn[ee]=se._jQueryInterface,i.default.fn[ee].Constructor=se,i.default.fn[ee].noConflict=function(){return i.default.fn[ee]=ne,se._jQueryInterface};var le="scrollspy",ue=i.default.fn[le],fe={offset:10,method:"auto",target:""},de={offset:"number",method:"string",target:"(string|element)"},ce=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,i.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,o="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,r=l.getSelectorFromElement(t);if(r&&(e=document.querySelector(r)),e){var a=e.getBoundingClientRect();if(a.width||a.height)return[i.default(e)[n]().top+o,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){i.default.removeData(this._element,"bs.scrollspy"),i.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=a({},fe,"object"==typeof t&&t?t:{})).target&&l.isElement(t.target)){var e=i.default(t.target).attr("id");e||(e=l.getUID(le),i.default(t.target).attr("id",e)),t.target="#"+e}return l.typeCheckConfig(le,t,de),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t li > .active":".active";n=(n=i.default.makeArray(i.default(o).find(a)))[n.length-1]}var s=i.default.Event("hide.bs.tab",{relatedTarget:this._element}),u=i.default.Event("show.bs.tab",{relatedTarget:n});if(n&&i.default(n).trigger(s),i.default(this._element).trigger(u),!u.isDefaultPrevented()&&!s.isDefaultPrevented()){r&&(e=document.querySelector(r)),this._activate(this._element,o);var f=function(){var e=i.default.Event("hidden.bs.tab",{relatedTarget:t._element}),o=i.default.Event("shown.bs.tab",{relatedTarget:n});i.default(n).trigger(e),i.default(t._element).trigger(o)};e?this._activate(e,e.parentNode,f):f()}}},e.dispose=function(){i.default.removeData(this._element,"bs.tab"),this._element=null},e._activate=function(t,e,n){var o=this,r=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?i.default(e).children(".active"):i.default(e).find("> li > .active"))[0],a=n&&r&&i.default(r).hasClass("fade"),s=function(){return o._transitionComplete(t,r,n)};if(r&&a){var u=l.getTransitionDurationFromElement(r);i.default(r).removeClass("show").one(l.TRANSITION_END,s).emulateTransitionEnd(u)}else s()},e._transitionComplete=function(t,e,n){if(e){i.default(e).removeClass("active");var o=i.default(e.parentNode).find("> .dropdown-menu .active")[0];o&&i.default(o).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}if(i.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),l.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&i.default(t.parentNode).hasClass("dropdown-menu")){var r=i.default(t).closest(".dropdown")[0];if(r){var a=[].slice.call(r.querySelectorAll(".dropdown-toggle"));i.default(a).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.tab");if(o||(o=new t(this),n.data("bs.tab",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();i.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),pe._jQueryInterface.call(i.default(this),"show")})),i.default.fn.tab=pe._jQueryInterface,i.default.fn.tab.Constructor=pe,i.default.fn.tab.noConflict=function(){return i.default.fn.tab=he,pe._jQueryInterface};var me=i.default.fn.toast,ge={animation:"boolean",autohide:"boolean",delay:"number"},ve={animation:!0,autohide:!0,delay:500},_e=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=i.default.Event("show.bs.toast");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),i.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),l.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,n).emulateTransitionEnd(o)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=i.default.Event("hide.bs.toast");i.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),i.default(this._element).off("click.dismiss.bs.toast"),i.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null},e._getConfig=function(t){return t=a({},ve,i.default(this._element).data(),"object"==typeof t&&t?t:{}),l.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;i.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),i.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.toast");if(o||(o=new t(this,"object"==typeof e&&e),n.data("bs.toast",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e](this)}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"DefaultType",get:function(){return ge}},{key:"Default",get:function(){return ve}}]),t}();i.default.fn.toast=_e._jQueryInterface,i.default.fn.toast.Constructor=_e,i.default.fn.toast.noConflict=function(){return i.default.fn.toast=me,_e._jQueryInterface},t.Alert=d,t.Button=h,t.Carousel=y,t.Collapse=S,t.Dropdown=Ft,t.Modal=qt,t.Popover=se,t.Scrollspy=ce,t.Tab=pe,t.Toast=_e,t.Tooltip=te,t.Util=l,Object.defineProperty(t,"__esModule",{value:!0})})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/llvm-build/checksec/templates/css/bootstrap.min.css b/llvm-build/checksec/templates/css/bootstrap.min.css new file mode 100644 index 0000000000000000000000000000000000000000..ef399d21ce7e2d18d0a931ea90c65461ff40a103 --- /dev/null +++ b/llvm-build/checksec/templates/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/llvm-build/checksec/templates/css/font-awesome.min.css b/llvm-build/checksec/templates/css/font-awesome.min.css new file mode 100644 index 0000000000000000000000000000000000000000..5578ea5d6f1c9b24843d461dab816a721e327ed9 --- /dev/null +++ b/llvm-build/checksec/templates/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/llvm-build/checksec/templates/failed_files_template.html b/llvm-build/checksec/templates/failed_files_template.html new file mode 100644 index 0000000000000000000000000000000000000000..3a0fa5bfd6f0ab181ae62abfa8a4151b2db9d18c --- /dev/null +++ b/llvm-build/checksec/templates/failed_files_template.html @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + +
+
+

Failed Files

+ Back +
+
+
+ {% for failed_file in check_file_list %} +
+ +
+ + + + + + + + + + + + + + + + + + + {% if failed_file.relro == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.canary == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.nx == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.pie == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.rpath == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.fortify == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.symbols == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.clangcfi == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.safestack == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.fortified == "passed" %} + + {% else %} + + {% endif %} + {% if failed_file.fortifiable == "passed" %} + + {% else %} + + {% endif %} + + +
relrocanarynxpierpathfortifysymbolsclangcfisafestackfortifiedfortify-able
{{failed_file.relro}}{{failed_file.relro}}{{failed_file.canary}}{{failed_file.canary}}{{failed_file.nx}}{{failed_file.nx}}{{failed_file.pie}}{{failed_file.pie}}{{failed_file.rpath}}{{failed_file.rpath}}{{failed_file.fortify}}{{failed_file.fortify}}{{failed_file.symbols}}{{failed_file.symbols}}{{failed_file.clangcfi}}{{failed_file.clangcfi}}{{failed_file.safestack}}{{failed_file.safestack}}{{failed_file.fortified}}{{failed_file.fortified}}{{failed_file.fortifiable}}{{failed_file.fortifiable}}
+
+
+ {% endfor %} +
+
+
+ + + \ No newline at end of file diff --git a/llvm-build/checksec/templates/fonts/FontAwesome.otf b/llvm-build/checksec/templates/fonts/FontAwesome.otf new file mode 100644 index 0000000000000000000000000000000000000000..401ec0f36e4f73b8efa40bd6f604fe80d286db70 Binary files /dev/null and b/llvm-build/checksec/templates/fonts/FontAwesome.otf differ diff --git a/llvm-build/checksec/templates/fonts/fontawesome-webfont.eot b/llvm-build/checksec/templates/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..e9f60ca953f93e35eab4108bd414bc02ddcf3928 Binary files /dev/null and b/llvm-build/checksec/templates/fonts/fontawesome-webfont.eot differ diff --git a/llvm-build/checksec/templates/fonts/fontawesome-webfont.svg b/llvm-build/checksec/templates/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000000000000000000000000000000000000..d7534c975b2a23edd3bd0b3f7e8c4be104f2a276 --- /dev/null +++ b/llvm-build/checksec/templates/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/llvm-build/checksec/templates/fonts/fontawesome-webfont.ttf b/llvm-build/checksec/templates/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..35acda2fa1196aad98c2adf4378a7611dd713aa3 Binary files /dev/null and b/llvm-build/checksec/templates/fonts/fontawesome-webfont.ttf differ diff --git a/llvm-build/checksec/templates/fonts/fontawesome-webfont.woff b/llvm-build/checksec/templates/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..400014a4b06eee3d0c0d54402a47ab2601b2862b Binary files /dev/null and b/llvm-build/checksec/templates/fonts/fontawesome-webfont.woff differ diff --git a/llvm-build/checksec/templates/fonts/fontawesome-webfont.woff2 b/llvm-build/checksec/templates/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4d13fc60404b91e398a37200c4a77b645cfd9586 Binary files /dev/null and b/llvm-build/checksec/templates/fonts/fontawesome-webfont.woff2 differ diff --git a/llvm-build/checksec/templates/index_files_template.html b/llvm-build/checksec/templates/index_files_template.html new file mode 100644 index 0000000000000000000000000000000000000000..8db2ae09935a51bb892c99a7bb6cc93193574ca5 --- /dev/null +++ b/llvm-build/checksec/templates/index_files_template.html @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + +
+
+

Test Summary

+
+
+
+ Start time/End Time: + {{summary_data._start_time}} - {{summary_data._end_time}} +
+
+
+
+ Execution Time: + {{summary_data._execution_time}} +
+
+
+
+ +
+ Total Files +
+
+ +
+ +
+
+ +
+ Failed Files +
+
+
+
+
+
+ + + + + + + + +
Check ItemsPassedFailed
+
+
+ {% for check_item in check_items %} +
+
+ + + + + + + + +
{{check_item._name}} + {% if check_item._name == "relro" %} + + + + + {% elif check_item._name == "canary" %} + + + + + {% elif check_item._name == "nx" %} + + + + + {% elif check_item._name == "pie" %} + + + + + {% elif check_item._name == "rpath" %} + + + + + {% elif check_item._name == "fortify" %} + + + + + {% elif check_item._name == "clangcfi" %} + + + + + {% elif check_item._name == "safestack" %} + + + + + {% endif %} + {{check_item._passed_num}}{{check_item._failed_num}}
+
+
+ {% if check_item._do_check == "true" %} +
+
+ +
+ + + + + + + + + + + + {% for failed_file in check_item._failed_list %} + + + + + {% for found_file in total_file_info %} + {% if found_file.filename == failed_file %} + {% if check_item._name == "relro" and found_file.relro != check_item._check_flag%} + + {% elif check_item._name == "canary" and found_file.canary != check_item._check_flag %} + + {% elif check_item._name == "nx" and found_file.nx != check_item._check_flag %} + + {% elif check_item._name == "pie" and found_file.pie != check_item._check_flag %} + + {% elif check_item._name == "rpath" and found_file.rpath != check_item._check_flag %} + + {% elif check_item._name == "fortify" and found_file.fortify_source != check_item._check_flag %} + + {% elif check_item._name == "symbols" and found_file.symbols != check_item._check_flag %} + + {% elif check_item._name == "clangcfi" and found_file.clangcfi != check_item._check_flag %} + + {% elif check_item._name == "safestack" and found_file.safestack != check_item._check_flag %} + + {% elif check_item._name == "fortified" and found_file.fortified != check_item._check_flag %} + + {% elif check_item._name == "fortify-able" and found_file.fortify_able != check_item._check_flag %} + + {% endif %} + {% endif %} + {% endfor %} + + + {% endfor %} + +
NoFailed FilesExpectedActualResults
{{loop.index}}{{failed_file}}{{check_item._check_flag}}{{found_file.relro}}{{found_file.canary}}{{found_file.nx}}{{found_file.pie}}{{found_file.rpath}}{{found_file.fortify_source}}{{found_file.symbols}}{{found_file.clangcfi}}{{found_file.safestack}}{{found_file.fortified}}{{found_file.fortify_able}}Failed
+
+
+
+
+
+ +
+ + + + + + + + + + + + {% for pass_file in check_item._passed_list %} + + + + + {% for found_file in total_file_info %} + {% if found_file.filename == pass_file %} + {% if check_item._name == "relro" and found_file.relro == check_item._check_flag%} + + {% elif check_item._name == "canary" and found_file.canary == check_item._check_flag %} + + {% elif check_item._name == "nx" and found_file.nx == check_item._check_flag %} + + {% elif check_item._name == "pie" and found_file.pie == check_item._check_flag %} + + {% elif check_item._name == "rpath" and found_file.rpath == check_item._check_flag %} + + {% elif check_item._name == "fortify" and found_file.fortify_source == check_item._check_flag %} + + {% elif check_item._name == "symbols" and found_file.symbols == check_item._check_flag %} + + {% elif check_item._name == "clangcfi" and found_file.clangcfi == check_item._check_flag %} + + {% elif check_item._name == "safestack" and found_file.safestack == check_item._check_flag %} + + {% elif check_item._name == "fortified" and found_file.fortified == check_item._check_flag %} + + {% elif check_item._name == "fortify-able" and found_file.fortify_able == check_item._check_flag %} + + {% endif %} + {% endif %} + {% endfor %} + + + {% endfor %} + +
NoPassed FilesExpected Actual Results
{{loop.index}}{{pass_file}}{{check_item._check_flag}}{{found_file.relro}}{{found_file.canary}}{{found_file.nx}}{{found_file.pie}}{{found_file.rpath}}{{found_file.fortify_source}}{{found_file.symbols}}{{found_file.clangcfi}}{{found_file.safestack}}{{found_file.fortified}}{{found_file.fortify_able}}Passed
+
+
+
+ {% else %} +
+
+ + + + + + + + + + {% for pass_file in check_item._passed_list %} + + + + {% for found_file in total_file_info %} + {% if found_file.filename == pass_file %} + {% if check_item.name == "relro" %} + + {% elif check_item._name == "canary" %} + + {% elif check_item._name == "nx" %} + + {% elif check_item._name == "pie" %} + + {% elif check_item._name == "rpath" %} + + {% elif check_item._name == "fortify" %} + + {% elif check_item._name == "symbols" %} + + {% elif check_item._name == "clangcfi" %} + + {% elif check_item._name == "safestack" %} + + {% elif check_item._name == "fortified" %} + + {% elif check_item._name == "fortify-able" %} + + {% endif %} + {% endif %} + {% endfor %} + + {% endfor %} + +
NoPassed FilesActual
{{loop.index}}{{pass_file}}{{found_file.relro}}{{found_file.canary}}{{found_file.nx}}{{found_file.pie}}{{found_file.rpath}}{{found_file.fortify_source}}{{found_file.symbols}}{{found_file.clangcfi}}{{found_file.safestack}}{{found_file.fortified}}{{found_file.fortify_able}}
+
+
+ {% endif %} + {% endfor %} +
+
+ + + \ No newline at end of file diff --git a/llvm-build/checksec/templates/jquery.min.js b/llvm-build/checksec/templates/jquery.min.js new file mode 100644 index 0000000000000000000000000000000000000000..0de648ed3b5201e4e05ace86e01f8ef201d2770e --- /dev/null +++ b/llvm-build/checksec/templates/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.4 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.4",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.cssHas=ce(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),d.cssHas||y.push(":has"),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType&&e.documentElement||e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 + + + + + + + + + + + + + + + + + + +
+
+

Total Files

+ Back +
+
+
+ {% for found_file in total_file_info %} +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
relrocanarynxpieclangcfisafestackrpathsymbolsfortifyfortifiedfortify-ablefile size
{{found_file.relro}}{{found_file.canary}}{{found_file.nx}}{{found_file.pie}}{{found_file.clangcfi}}{{found_file.safestack}}{{found_file.rpath}}{{found_file.symbols}}{{found_file.fortify_source}}{{found_file.fortified}}{{found_file.fortify_able}}{{found_file.file_single_size}}
+
+
+ {% endfor %} +
+
+
+ + + \ No newline at end of file diff --git a/llvm-build/cross_toolchain_builder.py b/llvm-build/cross_toolchain_builder.py index 81f167f617eb295f51e24658d0e9c42adefa3691..7f2bb792fa7815e9bd22292ceb7e7e22f9719adc 100644 --- a/llvm-build/cross_toolchain_builder.py +++ b/llvm-build/cross_toolchain_builder.py @@ -177,6 +177,16 @@ class CrossToolchainBuilder: ) ) + if self._build_config.enable_lzma_7zip: + lldb_defines['LLDB_ENABLE_LZMA'] = 'ON' + lldb_defines['LLDB_ENABLE_LZMA_7ZIP'] = 'ON' + lldb_defines['LIBLZMA_INCLUDE_DIRS'] = ( + self._build_utils.merge_install_dir('lzma', self._llvm_triple, 'include') + ) + lldb_defines['LIBLZMA_LIBRARIES'] = ( + self._build_utils.merge_install_dir('lzma', self._llvm_triple, 'lib', 'liblzma.so') + ) + if self._build_config.build_python or self._install_python_from_prebuilts: lldb_defines["LLDB_ENABLE_PYTHON"] = "ON" lldb_defines["LLDB_EMBED_PYTHON_HOME"] = "ON" @@ -199,7 +209,6 @@ class CrossToolchainBuilder: ) lldb_defines['Python3_RPATH'] = os.path.join('$ORIGIN', '..', 'python3', 'lib') - lldb_defines["LLDB_ENABLE_LZMA"] = "OFF" # Debug & Tuning if self._build_config.enable_monitoring: lldb_defines["LLDB_ENABLE_PERFORMANCE"] = "ON" @@ -216,6 +225,8 @@ class CrossToolchainBuilder: if self._build_config.build_python: self._python_builder.build() self._python_builder.prepare_for_package() + if self._build_config.enable_lzma_7zip: + self._llvm_libs.build_lzma(self._llvm_path, self._llvm_install, self._llvm_triple) self._build_utils.invoke_cmake( self._llvm_project_path, diff --git a/llvm-build/platform_package.sh b/llvm-build/platform_package.sh new file mode 100644 index 0000000000000000000000000000000000000000..e5cff03aff7a13179d2a23e64818dc2edd21756e --- /dev/null +++ b/llvm-build/platform_package.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# init variable +commit_id="" +date="" + +clang_linux_x86_64_tar="clang-dev-linux-x86_64.tar.gz" +clang_darwin_arm64_tar="clang-dev-darwin-arm64.tar.gz" +clang_darwin_x86_64_tar="clang-dev-darwin-x86_64.tar.gz" +clang_windows_x86_64_tar="clang-dev-windows-x86_64.tar.gz" +clang_ohos_arm64_tar="clang-dev-ohos-aarch64.tar.gz" +clang_linux_aarch64_tar="clang-dev-linux-aarch64.tar.gz" +libcxx_ndk_linux_x86_64_tar="libcxx-ndk-dev-linux-x86_64.tar.gz" +libcxx_ndk_darwin_x86_64_tar="libcxx-ndk-dev-darwin-x86_64.tar.gz" +libcxx_ndk_darwin_arm64_tar="libcxx-ndk-dev-darwin-arm64.tar.gz" +libcxx_ndk_windows_x86_64_tar="libcxx-ndk-dev-windows-x86_64.tar.gz" +libcxx_ndk_linux_aarch64_tar="libcxx-ndk-dev-linux-aarch64.tar.gz" + +clang_linux_x86_64="clang_linux-x86_64-${commit_id}-${date}" +clang_darwin_arm64="clang_darwin-arm64-${commit_id}-${date}" +clang_darwin_x86_64="clang_darwin-x86_64-${commit_id}-${date}" +clang_windows_x86_64="clang_windows-x86_64-${commit_id}-${date}" +clang_ohos_arm64="clang_ohos-arm64-${commit_id}-${date}" +clang_linux_aarch64="clang_linux_aarch64-${commit_id}-${date}" +libcxx_ndk_linux_x86_64="libcxx-ndk_linux-x86_64-${commit_id}-${date}" +libcxx_ndk_darwin_x86_64="libcxx-ndk_darwin-x86_64-${commit_id}-${date}" +libcxx_ndk_darwin_arm64="libcxx-ndk_darwin-arm64-${commit_id}-${date}" +libcxx_ndk_windows_x86_64="libcxx-ndk_windows-x86_64-${commit_id}-${date}" +libcxx_ndk_ohos_arm64="libcxx_ndk_ohos-arm64-${commit_id}-${date}" +libcxx_ndk_linux_aarch64="libcxx-ndk_linux-aarch64-${commit_id}-${date}" +llvm_list=($clang_linux_x86_64 $clang_darwin_arm64 $clang_darwin_x86_64 $clang_windows_x86_64 $clang_ohos_arm64 $clang_linux_aarch64 $libcxx_ndk_linux_x86_64 $libcxx_ndk_darwin_x86_64 $libcxx_ndk_darwin_arm64 $libcxx_ndk_windows_x86_64 $libcxx_ndk_ohos_arm64 $libcxx_ndk_linux_aarch64) + +# decompress file and rename +tar -xvf ${clang_linux_x86_64_tar} +mv clang-dev ${clang_linux_x86_64} +tar -xvf ${clang_darwin_arm64_tar} +mv clang-dev ${clang_darwin_arm64} +tar -xvf ${clang_darwin_x86_64_tar} +mv clang-dev ${clang_darwin_x86_64} +tar -xvf ${clang_windows_x86_64_tar} +mv clang-dev ${clang_windows_x86_64} +tar -xvf ${clang_ohos_arm64_tar} +mv clang-dev ${clang_ohos_arm64} +tar -xvf ${clang_linux_aarch64_tar} +mv clang-dev ${clang_linux_aarch64} +tar -xvf ${libcxx_ndk_linux_x86_64_tar} +mv libcxx-ndk ${libcxx_ndk_linux_x86_64} +tar -xvf ${libcxx_ndk_darwin_x86_64_tar} +mv libcxx-ndk ${libcxx_ndk_darwin_x86_64} +tar -xvf ${libcxx_ndk_darwin_arm64_tar} +mv libcxx-ndk ${libcxx_ndk_darwin_arm64} +tar -xvf ${libcxx_ndk_windows_x86_64_tar} +mv libcxx-ndk ${libcxx_ndk_windows_x86_64} +cp -ar ${libcxx_ndk_linux_x86_64} ${libcxx_ndk_ohos_arm64} +tar -xvf ${libcxx_ndk_linux_aarch64_tar} +mv libcxx-ndk ${libcxx_ndk_linux_aarch64} + +#clang-dev-darwin-arm64 +cp -rf ${clang_linux_x86_64}/lib/aarch64-linux-ohos ${clang_darwin_arm64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-liteos-ohos ${clang_darwin_arm64}/lib +cp -rf ${clang_linux_x86_64}/include/libcxx-ohos ${clang_darwin_arm64}/include +cp -rf ${clang_linux_x86_64}/lib/arm-linux-ohos ${clang_darwin_arm64}/lib +cp -rf ${clang_linux_x86_64}/lib/loongarch64-linux-ohos ${clang_darwin_arm64}/lib +cp -rf ${clang_linux_x86_64}/lib/x86_64-linux-ohos ${clang_darwin_arm64}/lib +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/bin ${clang_darwin_arm64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/profile ${clang_darwin_arm64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/fuzzer ${clang_darwin_arm64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/share ${clang_darwin_arm64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/sanitizer ${clang_darwin_arm64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/lib/ ${clang_darwin_arm64}/lib/clang/15.0.4 + +#clang-dev-darwin-x86_64 +cp -rf ${clang_linux_x86_64}/lib/aarch64-linux-ohos ${clang_darwin_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-liteos-ohos ${clang_darwin_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-linux-ohos ${clang_darwin_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/x86_64-linux-ohos ${clang_darwin_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/loongarch64-linux-ohos ${clang_darwin_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/bin ${clang_darwin_x86_64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/share ${clang_darwin_x86_64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/lib ${clang_darwin_x86_64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/profile ${clang_darwin_x86_64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/fuzzer ${clang_darwin_x86_64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/sanitizer ${clang_darwin_x86_64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/include/libcxx-ohos ${clang_darwin_x86_64}/include + +#clang-dev-windows-x86_64 +cp -rf ${clang_linux_x86_64}/include/libcxx-ohos ${clang_windows_x86_64}/include +cp -rf ${clang_linux_x86_64}/lib/aarch64-linux-ohos ${clang_windows_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-liteos-ohos ${clang_windows_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-linux-ohos ${clang_windows_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/x86_64-linux-ohos ${clang_windows_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/loongarch64-linux-ohos ${clang_windows_x86_64}/lib +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/bin ${clang_windows_x86_64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/share ${clang_windows_x86_64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/lib ${clang_windows_x86_64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/profile ${clang_windows_x86_64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/fuzzer ${clang_windows_x86_64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/sanitizer ${clang_windows_x86_64}/lib/clang/15.0.4/include + + +#clang-dev-ohos-aarch64 +cp -rf ${clang_linux_x86_64}/include/libcxx-ohos ${clang_ohos_arm64}/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/bin ${clang_ohos_arm64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/share ${clang_ohos_arm64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/lib ${clang_ohos_arm64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/profile ${clang_ohos_arm64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/fuzzer ${clang_ohos_arm64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/sanitizer ${clang_ohos_arm64}/lib/clang/15.0.4/include + +#clang-dev-linux-aarch64 +cp -rf ${clang_linux_x86_64}/include/libcxx-ohos ${clang_linux_aarch64}/include +cp -rf ${clang_linux_x86_64}/lib/aarch64-linux-ohos ${clang_linux_aarch64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-liteos-ohos ${clang_linux_aarch64}/lib +cp -rf ${clang_linux_x86_64}/lib/arm-linux-ohos ${clang_linux_aarch64}/lib +cp -rf ${clang_linux_x86_64}/lib/x86_64-linux-ohos ${clang_linux_aarch64}/lib +cp -rf ${clang_linux_x86_64}/lib/loongarch64-linux-ohos ${clang_linux_aarch64}/lib +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/bin ${clang_linux_aarch64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/share ${clang_linux_aarch64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/lib ${clang_linux_aarch64}/lib/clang/15.0.4 +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/profile ${clang_linux_aarch64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/fuzzer ${clang_linux_aarch64}/lib/clang/15.0.4/include +cp -rf ${clang_linux_x86_64}/lib/clang/15.0.4/include/sanitizer ${clang_linux_aarch64}/lib/clang/15.0.4/include + + +#archive +mkdir target_location +function package_llvm(){ +for i in ${llvm_list[@]} +do + tar zcvf target_location/${i}.tar.gz ${i} + sha256sum target_location/${i}.tar.gz |awk '{print $1}' > target_location/${i}.tar.gz.sha256 +done +} + +package_llvm diff --git a/llvm/include/llvm/PARTS/Parts.h b/llvm/include/llvm/PARTS/Parts.h index 4c23975f134350c455f4d92abdb7ceb7f119c55f..ad62b5c6358d9ba40afcf35ce44afd023625655c 100644 --- a/llvm/include/llvm/PARTS/Parts.h +++ b/llvm/include/llvm/PARTS/Parts.h @@ -38,6 +38,7 @@ bool useDataFieldTag(); bool useDataFieldProtection(); PartsBeCfiType getBeCfiType(); uint16_t getTypeIdFor(const Type *T); +std::string getLLVMRevision(); } } #endif \ No newline at end of file diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h index 033482977a105cae0af9466a0d42756aec9b1116..55783ac776f9d979dedd897ca782e02771fb26db 100644 --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -1451,6 +1451,12 @@ public: return *this; } + // OHOS_LOCAL begin + intptr_t get_handler() { + return State->IterationHandle; + } + // OHOS_LOCAL end + const directory_entry &operator*() const { return State->CurrentEntry; } const directory_entry *operator->() const { return &State->CurrentEntry; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 54af144299077b0fecc36c893a78809d0d86a385..9945b795dc4dd79f91f7fae24c1d8d75b9f62776 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1071,6 +1071,13 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { if (auto *CU = CUMap.lookup(DIUnit)) return *CU; + if (useSplitDwarf() && + !shareAcrossDWOCUs() && + (!DIUnit->getSplitDebugInlining() || + DIUnit->getEmissionKind() == DICompileUnit::FullDebug) && + !CUMap.empty()) { + return *CUMap.begin()->second; + } CompilationDir = DIUnit->getDirectory(); auto OwnedUnit = std::make_unique( @@ -1274,6 +1281,8 @@ void DwarfDebug::finalizeModuleInfo() { if (CUMap.size() > 1) DWOName = Asm->TM.Options.MCOptions.SplitDwarfFile; + bool HasEmittedSplitCU = false; + // Handle anything that needs to be done on a per-unit basis after // all other generation. for (const auto &P : CUMap) { @@ -1292,6 +1301,10 @@ void DwarfDebug::finalizeModuleInfo() { bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty(); if (HasSplitUnit) { + (void)HasEmittedSplitCU; + assert((shareAcrossDWOCUs() || !HasEmittedSplitCU) && + "Multiple CUs emitted into a single dwo file"); + HasEmittedSplitCU = true; dwarf::Attribute attrDWOName = getDwarfVersion() >= 5 ? dwarf::DW_AT_dwo_name : dwarf::DW_AT_GNU_dwo_name; @@ -2203,7 +2216,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); assert(!FnScope || SP == FnScope->getScopeNode()); - DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit()); + DwarfCompileUnit &TheCU = getOrCreateDwarfCompileUnit(SP->getUnit()); if (TheCU.getCUNode()->isDebugDirectivesOnly()) { PrevLabel = nullptr; CurFn = nullptr; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 81238b0fe0d2872f013f691cdb362143a9431f66..151bf376e0c5ec3b364e019a79a5a610dc477f88 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -544,7 +544,7 @@ void DwarfUnit::addAccess(DIE &Die, DINode::DIFlags Flags) { } DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) { - if (!Context || isa(Context)) + if (!Context || isa(Context) || isa(Context)) return &getUnitDie(); if (auto *T = dyn_cast(Context)) return getOrCreateTypeDIE(T); diff --git a/llvm/lib/PARTS/Parts.cpp b/llvm/lib/PARTS/Parts.cpp index a49b889829a688664d2a74c88d4898a355b8466f..a013a62a926113304d2d4da3a38acda84e253505 100644 --- a/llvm/lib/PARTS/Parts.cpp +++ b/llvm/lib/PARTS/Parts.cpp @@ -136,4 +136,13 @@ uint16_t llvm::PARTS::getTypeIdFor(const Type *T) uint16_t TheTypeId = getTypeId(Buf); TypeIdCache.emplace(T, TheTypeId); return TheTypeId; +} + +std::string llvm::PARTS::getLLVMRevision() +{ +#ifdef LLVM_REVISION + return LLVM_REVISION; +#else + return ""; +#endif } \ No newline at end of file diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp index 27c04177e894d141b0ff5456229391d687de129e..cbb96e657f0b694ab28dbaf4c8d35236474b8f10 100644 --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -673,6 +673,12 @@ bool TailRecursionEliminator::eliminateCall(CallInst *CI) { for (unsigned I = 0, E = CI->arg_size(); I != E; ++I) { if (CI->isByValArgument(I)) { copyLocalTempOfByValueOperandIntoArguments(CI, I); + // When eliminating a tail call, we modify the values of the arguments. + // Therefore, if the byval parameter has a readonly attribute, we have to + // remove it. It is safe because, from the perspective of a caller, the + // byval parameter is always treated as "readonly," even if the readonly + // attribute is removed. + F.removeParamAttr(I, Attribute::ReadOnly); ArgumentPHIs[I]->addIncoming(F.getArg(I), BB); } else ArgumentPHIs[I]->addIncoming(CI->getArgOperand(I), BB); diff --git a/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll b/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll index ac5a10652ba92792c708c08994474b2bc011ea89..03a444976e3e9e0427210be0cf2bc40239c16a6f 100644 --- a/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll +++ b/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll @@ -8,10 +8,12 @@ ; CHECK-NEXT: DW_AT_decl_file (0x02) ; CHECK-NEXT: DW_AT_decl_line (4) -; Function Attrs: noinline nounwind optnone uwtable mustprogress -define dso_local void @_Z2f1v() local_unnamed_addr #0 !dbg !12 { +; Function Attrs: norecurse nounwind uwtable mustprogress +define dso_local i32 @main() local_unnamed_addr #2 !dbg !26 { entry: - ret void, !dbg !15 + tail call void @_Z2f1v() #3, !dbg !28 + tail call void @_Z2f1v() #3, !dbg !30 + ret i32 0, !dbg !32 } ; Function Attrs: nounwind uwtable mustprogress @@ -21,6 +23,12 @@ entry: ret void, !dbg !22 } +; Function Attrs: noinline nounwind optnone uwtable mustprogress +define dso_local void @_Z2f1v() local_unnamed_addr #0 !dbg !12 { +entry: + ret void, !dbg !15 +} + ; Function Attrs: nounwind uwtable mustprogress define dso_local void @_Z2f2v() local_unnamed_addr #1 !dbg !23 { entry: @@ -28,14 +36,6 @@ entry: ret void, !dbg !25 } -; Function Attrs: norecurse nounwind uwtable mustprogress -define dso_local i32 @main() local_unnamed_addr #2 !dbg !26 { -entry: - tail call void @_Z2f1v() #3, !dbg !28 - tail call void @_Z2f1v() #3, !dbg !30 - ret i32 0, !dbg !32 -} - attributes #0 = { noinline nounwind optnone uwtable mustprogress "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #1 = { nounwind uwtable mustprogress "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #2 = { norecurse nounwind uwtable mustprogress "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } diff --git a/llvm/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll b/llvm/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll index 7b73abacdf5566ac2e2ade889a3de17b62c8acfd..4cc232c970ed4159391a704af8f72749d4c44cfa 100644 --- a/llvm/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll +++ b/llvm/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll @@ -1,12 +1,12 @@ ; RUN: llc -mtriple=x86_64-linux -split-dwarf-cross-cu-references -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s -; RUN: llvm-objdump -r %t | FileCheck %s -; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=INFO --check-prefix=DWO --check-prefix=CROSS %s -; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=INFO %s +; RUN: llvm-objdump -r %t | FileCheck --check-prefix=CHECK --check-prefix=RELO_CROSS %s +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=DWO --check-prefix=CROSS %s +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL %s ; RUN: llc -mtriple=x86_64-linux -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s -; RUN: llvm-objdump -r %t | FileCheck %s +; RUN: llvm-objdump -r %t | FileCheck --check-prefix=CHECK %s ; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=DWO --check-prefix=NOCROSS %s -; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=INFO %s +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL %s ; Testing cross-CU references for types, subprograms, and variables ; Built from code something like this: @@ -48,8 +48,8 @@ ; CHECK-NOT: RELOCATION RECORDS ; Expect one relocation in debug_info, from the inlined f1 in foo to its ; abstract origin in bar -; CHECK: R_X86_64_32 .debug_info -; CHECK-NOT: RELOCATION RECORDS +; RELO_CROSS: R_X86_64_32 .debug_info +; Expect no relocations in debug_info when disabling multiple CUs in Split DWARF ; CHECK-NOT: .debug_info ; CHECK: RELOCATION RECORDS ; CHECK-NOT: .rel{{a?}}.debug_info.dwo @@ -75,29 +75,22 @@ ; DWO: DW_TAG_formal_parameter ; DWO: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[F1T]]} -; ALL: Compile Unit -; ALL: DW_TAG_compile_unit -; DWO: DW_AT_name {{.*}} "bar.cpp" -; NOCROSS: 0x[[BAR_F1:.*]]: DW_TAG_subprogram -; NOCROSS: DW_AT_name {{.*}} "f1" -; NOCROSS: 0x[[BAR_F1T:.*]]: DW_TAG_formal_parameter -; NOCROSS: DW_AT_name {{.*}} "t" -; NOCROSS: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[BAR_T1:.*]]} -; NOCROSS: NULL -; NOCROSS: 0x[[BAR_T1]]: DW_TAG_structure_type -; NOCROSS: DW_AT_name {{.*}} "t1" +; NOCROSS-NOT: DW_TAG_compile_unit +; CROSS: Compile Unit +; CROSS: DW_TAG_compile_unit +; CROSS: DW_AT_name {{.*}} "bar.cpp" ; ALL: DW_TAG_subprogram ; ALL: DW_AT_name {{.*}} "bar" ; DWO: DW_TAG_formal_parameter ; DWO: DW_AT_name {{.*}} "t" ; CROSS: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[T1]] -; NOCROSS: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[BAR_T1]]} +; NOCROSS: DW_AT_type [DW_FORM_ref4] {{.*}}{0x[[T1]]} ; ALL: DW_TAG_inlined_subroutine -; INFO: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[F1]] -; NOCROSS: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[BAR_F1]]} +; CROSS: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[F1]] +; NOCROSS: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[F1]]} ; DWO: DW_TAG_formal_parameter ; CROSS: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[F1T]] -; NOCROSS: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[BAR_F1T]] +; NOCROSS: DW_AT_abstract_origin [DW_FORM_ref4] {{.*}}{0x[[F1T]] %struct.t1 = type { i32 } diff --git a/llvm/test/DebugInfo/X86/string-offsets-table-order.ll b/llvm/test/DebugInfo/X86/string-offsets-table-order.ll index ca159eea615f68465f5d8e6d5b3036ac1bab1010..6a61c458dec3e4a0cfa5ca95bba6bc369d76270b 100644 --- a/llvm/test/DebugInfo/X86/string-offsets-table-order.ll +++ b/llvm/test/DebugInfo/X86/string-offsets-table-order.ll @@ -11,13 +11,10 @@ ; in different order. ; CHECK: .debug_info contents: -; CHECK: DW_TAG_skeleton_unit -; CHECK: DW_AT_comp_dir [DW_FORM_strx1] (indexed (00000000) string = "X3") -; CHECK: DW_TAG_skeleton_unit -; CHECK: DW_AT_comp_dir [DW_FORM_strx1] (indexed (00000001) string = "X2") -; CHECK: DW_TAG_skeleton_unit -; CHECK: DW_AT_comp_dir [DW_FORM_strx1] (indexed (00000002) string = "X1") -; CHECK: .debug_info.dwo contents: +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_name [DW_FORM_strx1] (indexed (00000000) string = "X1") +; CHECK: DW_AT_name [DW_FORM_strx1] (indexed (00000002) string = "X2") +; CHECK: DW_AT_name [DW_FORM_strx1] (indexed (00000003) string = "X3") ; CHECK: .debug_str contents: ; CHECK: 0x[[X3:[0-9a-f]*]]: "X3" @@ -26,11 +23,9 @@ ; CHECK: .debug_str_offsets contents: ; CHECK: Format = DWARF32, Version = 5 -; CHECK-NEXT: [[X3]] "X3" -; CHECK-NEXT: [[X2]] "X2" -; CHECK-NEXT: [[X1]] "X1" -; CHECK-NEXT: "foo.dwo" -; CHECK-EMPTY: +; CHECK: [[X3]] "X3" +; CHECK: [[X1]] "X1" +; CHECK: [[X2]] "X2" diff --git a/llvm/test/Transforms/PhaseOrdering/pr64289-tce-adapt.ll b/llvm/test/Transforms/PhaseOrdering/pr64289-tce-adapt.ll new file mode 100644 index 0000000000000000000000000000000000000000..e23e0be79ac1f8c19b8ffbee246731e6ada1872c --- /dev/null +++ b/llvm/test/Transforms/PhaseOrdering/pr64289-tce-adapt.ll @@ -0,0 +1,28 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -O3 < %s | FileCheck %s + +; A miscompilation found on https://github.com/llvm/llvm-project/issues/64289. +; 1. PostOrderFunctionAttrsPass added readonly to the parameter. +; 2. TailCallElimPass modified the parameter but kept readonly. +; 3. LICMPass incorrectly hoisted the load instruction. + +define void @pr64289(ptr noalias byval(i64) %x) { +; CHECK-LABEL: @pr64289( +; CHECK-NOT: readonly +; CHECK-SAME: byval +; CHECK-NEXT: start: +; +start: + %new_x = alloca i64, align 8 + %x_val = load i64, ptr %x, align 8 + %is_zero = icmp eq i64 %x_val, 0 + br i1 %is_zero, label %end, label %recurse + +recurse: + store i64 0, ptr %new_x, align 8 + call void @pr64289(ptr %new_x) + br label %end + +end: + ret void +} diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 0242e0b75af33f7d24b8827ef49c11595f806667..4eceea37a05d1fdfb3e7bf290a81aedbfa9bac62 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -1734,7 +1734,11 @@ def executeShTest(test, litConfig, useExternalSh, if litConfig.noExecute: return lit.Test.Result(Test.PASS) - + # OHOS_LOCAL begin + # Setting environment variables on a remote device, this command is used only for OpenMP test. + if (test.config.name == 'libomp' or test.config.name == 'OMPT multiplex') and test.config.operating_system == 'OHOS': + script = replaceEnvrunForScript(script) + # OHOS_LOCAL end tmpDir, tmpBase = getTempPaths(test) substitutions = list(extra_substitutions) substitutions += getDefaultSubstitutions(test, tmpDir, tmpBase, @@ -1742,5 +1746,18 @@ def executeShTest(test, litConfig, useExternalSh, conditions = { feature: True for feature in test.config.available_features } script = applySubstitutions(script, substitutions, conditions, recursion_limit=test.config.recursiveExpansionLimit) - return _runShTest(test, litConfig, useExternalSh, script, tmpBase) + +def replaceEnvrunForScript(script): + """ + Replace `env xxxx %libomp-run` in the script with `%libomp-env-run env xxxx %root-path%t`. + """ + newScript = [] + pattern = re.compile(r"(env\s+.*?)(\s+%libomp-run)") + replacement = r'%libomp-env-run \1 %root-path%t' + for ln in script: + if pattern.search(ln): + newScript.append(pattern.sub(replacement, ln)) + else: + newScript.append(ln) + return newScript \ No newline at end of file diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index 55e2a764d8fa60055d98c3905d5f1cfa34fc55cb..e5d752f017aadd4ce6aa4d621e741c4ab735dff6 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -43,6 +43,10 @@ class TestingConfig(object): 'ADB', 'ANDROID_SERIAL', 'SSH_AUTH_SOCK', + 'HDC', + 'HDC_SERVER', + 'HDC_TARGET_SERIAL', + 'LIB_PATH_ON_TARGET', 'SANITIZER_IGNORE_CVE_2016_2143', 'TMPDIR', 'TMP', diff --git a/openmp/runtime/src/kmp_config.h.cmake b/openmp/runtime/src/kmp_config.h.cmake index 40d20115c9ec089d6b1c36e0284dd01d0db736a8..7e8dad4ca6c9f4ba4e28475955745acfd6429c41 100644 --- a/openmp/runtime/src/kmp_config.h.cmake +++ b/openmp/runtime/src/kmp_config.h.cmake @@ -134,9 +134,9 @@ # define KMP_GOMP_COMPAT #endif -// use shared memory with dynamic library (except Android, where shm_* +// use shared memory with dynamic library (except Android and OHOS, where shm_* // functions don't exist). -#if KMP_OS_UNIX && KMP_DYNAMIC_LIB && !__ANDROID__ +#if KMP_OS_UNIX && KMP_DYNAMIC_LIB && !__ANDROID__ && !__OHOS__ #define KMP_USE_SHM #endif #endif // KMP_CONFIG_H diff --git a/openmp/runtime/test/affinity/format/nested.c b/openmp/runtime/test/affinity/format/nested.c index db2e607bf8e65a6ed75677569784d4ae9ecd75aa..1d8bc8cb35c3d59bad6f55a99a2320b2e0b0c5fb 100644 --- a/openmp/runtime/test/affinity/format/nested.c +++ b/openmp/runtime/test/affinity/format/nested.c @@ -1,4 +1,4 @@ -// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES=threads OMP_PROC_BIND=spread,close %libomp-run | %python %S/check.py -c 'CHECK' %s +// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES=threads OMP_PROC_BIND=spread,close %platform-flag %libomp-run | %python %S/check.py -c 'CHECK' %s // REQUIRES: affinity #include diff --git a/openmp/runtime/test/affinity/format/nested2.c b/openmp/runtime/test/affinity/format/nested2.c index f259aeace0d6d9edb5c098049c541b1476c5a7e8..059ea6a9c425e67a7f613c9b892ed7d9b2549e5d 100644 --- a/openmp/runtime/test/affinity/format/nested2.c +++ b/openmp/runtime/test/affinity/format/nested2.c @@ -1,4 +1,4 @@ -// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES=threads OMP_PROC_BIND=spread,close KMP_HOT_TEAMS_MAX_LEVEL=2 %libomp-run | %python %S/check.py -c 'CHECK' %s +// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES=threads OMP_PROC_BIND=spread,close KMP_HOT_TEAMS_MAX_LEVEL=2 %platform-flag %libomp-run | %python %S/check.py -c 'CHECK' %s #include #include diff --git a/openmp/runtime/test/affinity/format/nested_mixed.c b/openmp/runtime/test/affinity/format/nested_mixed.c index 288e1c21c2bf9c743b0cead61acb3bae2d8cf0ed..dd1376a07b64b1bd5937de41d360d51781bfa4d6 100644 --- a/openmp/runtime/test/affinity/format/nested_mixed.c +++ b/openmp/runtime/test/affinity/format/nested_mixed.c @@ -1,4 +1,4 @@ -// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %libomp-run | %python %S/check.py -c 'CHECK' %s +// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %platform-flag %libomp-run | %python %S/check.py -c 'CHECK' %s #include #include diff --git a/openmp/runtime/test/affinity/format/nested_serial.c b/openmp/runtime/test/affinity/format/nested_serial.c index 70ccf5be3c84e506d7065335d8ac90dc1a37c467..5e0ffc9cbbaf5a69fc5cccb9314bd074bd9ff042 100644 --- a/openmp/runtime/test/affinity/format/nested_serial.c +++ b/openmp/runtime/test/affinity/format/nested_serial.c @@ -1,4 +1,4 @@ -// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %libomp-run | %python %S/check.py -c 'CHECK' %s +// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %platform-flag %libomp-run | %python %S/check.py -c 'CHECK' %s #include #include diff --git a/openmp/runtime/test/lit.cfg b/openmp/runtime/test/lit.cfg index 45e65d9c3ef6ba020de4aada01742cf3a108c9da..d4507c06d86500a4a217962ff79f3ebffc1acb35 100644 --- a/openmp/runtime/test/lit.cfg +++ b/openmp/runtime/test/lit.cfg @@ -51,6 +51,9 @@ if config.has_omit_frame_pointer_flag: config.test_flags = " -I " + config.omp_header_directory + flags config.test_flags_use_compiler_omp_h = flags +# OHOS LOCAL +if config.operating_system == 'OHOS': + config.test_flags += " --target=aarch64-linux-ohos" # extra libraries libs = "" @@ -105,7 +108,7 @@ if 'Linux' in config.operating_system: if config.operating_system == 'NetBSD': config.available_features.add("netbsd") -if config.operating_system in ['Linux', 'Windows']: +if config.operating_system in ['Linux', 'Windows', 'OHOS']: config.available_features.add('affinity') import multiprocessing @@ -134,7 +137,27 @@ config.substitutions.append(("%libomp-compile", \ "%clang %openmp_flags %flags %s -o %t" + libs)) config.substitutions.append(("%libomp-c99-compile", \ "%clang %openmp_flags %flags -std=c99 %s -o %t" + libs)) -config.substitutions.append(("%libomp-run", "%t")) + +# OHOS_LOCAL begin +if config.operating_system == 'OHOS': + # Settings required to run test cases remotely on OHOS + if not (config.environment.get('HDC') != None and config.environment.get('HDC_SERVER') != None + and config.environment.get('HDC_TARGET_SERIAL') != None and config.environment.get('LIB_PATH_ON_TARGET') != None): + raise ValueError("Error: One or more environment variables in HDC, HDC_SERVER, HDC_TARGET_SERIAL or LIB_PATH_ON_TARGET are not set.") + hdc = f"{config.environment['HDC']} -s {config.environment['HDC_SERVER']} -t {config.environment['HDC_TARGET_SERIAL']}" + cmd_set_ld_library_path = f"env LD_LIBRARY_PATH={config.environment['LIB_PATH_ON_TARGET']}:$LD_LIBRARY_PATH" + cmd_mkdir_to_device = f"{hdc} shell mkdir -p /data/local/temp/$(dirname %t)" + cmd_push_to_device = f"{hdc} file send %t %root-path%t" + cmd_chmod_to_test = f"{hdc} shell chmod 755 %root-path%t" + cmd_run_on_device = f"{hdc} shell {cmd_set_ld_library_path} %root-path%t" + config.substitutions.append(("%libomp-env-run", f"{cmd_mkdir_to_device} && {cmd_push_to_device} && {cmd_chmod_to_test} && {hdc} shell {cmd_set_ld_library_path}")) + config.substitutions.append(("%libomp-run", f"{cmd_mkdir_to_device} && {cmd_push_to_device} && {cmd_chmod_to_test} && {cmd_run_on_device}")) + config.substitutions.append(("%root-path", "/data/local/temp")) + config.substitutions.append(("%platform-flag", "KMP_WARNINGS=false")) +# OHOS_LOCAL end +else: + config.substitutions.append(("%libomp-run", "%t")) + config.substitutions.append(("%platform-flag", "")) config.substitutions.append(("%clangXX", config.test_cxx_compiler)) config.substitutions.append(("%clang", config.test_c_compiler)) config.substitutions.append(("%openmp_flags", config.test_openmp_flags)) diff --git a/openmp/tools/multiplex/tests/lit.cfg b/openmp/tools/multiplex/tests/lit.cfg index 69df2fd944cb456d69aae10e3d1af3175ed28dd3..3e0666d360e6d79275abe997f102cffcd297c5f5 100644 --- a/openmp/tools/multiplex/tests/lit.cfg +++ b/openmp/tools/multiplex/tests/lit.cfg @@ -67,6 +67,10 @@ append_dynamic_library_path(config.test_obj_root+"/..") if config.operating_system == 'Darwin': config.test_flags += " -Wl,-rpath," + config.omp_library_dir +# OHOS LOCAL +if config.operating_system == 'OHOS': + config.test_flags += " --target=aarch64-linux-ohos" + # Find the SDK on Darwin if config.operating_system == 'Darwin': cmd = subprocess.Popen(['xcrun', '--show-sdk-path'], @@ -90,7 +94,24 @@ config.substitutions.append(("%libomp-compile", \ "%clang %cflags %s -o %t")) config.substitutions.append(("%libomp-tool", \ "%clang %cflags -shared -fPIC -g")) -config.substitutions.append(("%libomp-run", "%t")) + +# OHOS_LOCAL begin +if config.operating_system == 'OHOS': + if not (config.environment.get('HDC') != None and config.environment.get('HDC_SERVER') != None + and config.environment.get('HDC_TARGET_SERIAL') != None and config.environment.get('LIB_PATH_ON_TARGET') != None): + raise ValueError("Error: One or more environment variables in HDC, HDC_SERVER, HDC_TARGET_SERIAL or LIB_PATH_ON_TARGET are not set.") + hdc = f"{config.environment['HDC']} -s {config.environment['HDC_SERVER']} -t {config.environment['HDC_TARGET_SERIAL']}" + cmd_set_ld_library_path = f"env LD_LIBRARY_PATH={config.environment['LIB_PATH_ON_TARGET']}:$LD_LIBRARY_PATH" + cmd_mkdir_to_device = f"{hdc} shell mkdir -p /data/local/temp/$(dirname %t)" + cmd_push_to_device = f"{hdc} file send %t %root-path%t" + cmd_chmod_to_test = f"{hdc} shell chmod 755 %root-path%t" + cmd_run_on_device = f"{hdc} shell {cmd_set_ld_library_path} %root-path%t" + config.substitutions.append(("%libomp-env-run", f"{cmd_mkdir_to_device} && {cmd_push_to_device} && {cmd_chmod_to_test} && {hdc} shell {cmd_set_ld_library_path}")) + config.substitutions.append(("%libomp-run", f"{cmd_mkdir_to_device} && {cmd_push_to_device} && {cmd_chmod_to_test} && {cmd_run_on_device}")) + config.substitutions.append(("%root-path", "/data/local/temp")) +# OHOS_LOCAL end +else: + config.substitutions.append(("%libomp-run", "%t")) config.substitutions.append(("%clang", config.test_c_compiler)) config.substitutions.append(("%openmp_flag", config.test_openmp_flags)) config.substitutions.append(("%cflags", config.test_flags))