//===- Core/YamlKeyValues.cpp - Reads YAML --------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "YamlKeyValues.h" #include "llvm/Support/ErrorHandling.h" #include "lld/Core/File.h" #include namespace lld { namespace yaml { const char* const KeyValues::nameKeyword = "name"; const char* const KeyValues::refNameKeyword = "ref-name"; const char* const KeyValues::definitionKeyword = "definition"; const char* const KeyValues::scopeKeyword = "scope"; const char* const KeyValues::contentTypeKeyword = "type"; const char* const KeyValues::deadStripKindKeyword = "dead-strip"; const char* const KeyValues::sectionChoiceKeyword = "section-choice"; const char* const KeyValues::interposableKeyword = "interposable"; const char* const KeyValues::mergeKeyword = "merge"; const char* const KeyValues::isThumbKeyword = "is-thumb"; const char* const KeyValues::isAliasKeyword = "is-alias"; const char* const KeyValues::sectionNameKeyword = "section-name"; const char* const KeyValues::contentKeyword = "content"; const char* const KeyValues::loadNameKeyword = "load-name"; const char* const KeyValues::sizeKeyword = "size"; const char* const KeyValues::valueKeyword = "value"; const char* const KeyValues::fixupsKeyword = "fixups"; const char* const KeyValues::permissionsKeyword = "permissions"; const char* const KeyValues::canBeNullKeyword = "can-be-null"; const char* const KeyValues::fixupsKindKeyword = "kind"; const char* const KeyValues::fixupsOffsetKeyword = "offset"; const char* const KeyValues::fixupsTargetKeyword = "target"; const char* const KeyValues::fixupsAddendKeyword = "addend"; const char* const KeyValues::fileAtomsKeyword = "atoms"; const char* const KeyValues::fileKindKeyword = "kind"; const char* const KeyValues::fileMembersKeyword = "members"; const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular; const DefinedAtom::Scope KeyValues::scopeDefault = DefinedAtom::scopeTranslationUnit; const DefinedAtom::ContentType KeyValues::contentTypeDefault = DefinedAtom::typeData; const DefinedAtom::DeadStripKind KeyValues::deadStripKindDefault = DefinedAtom::deadStripNormal; const DefinedAtom::SectionChoice KeyValues::sectionChoiceDefault = DefinedAtom::sectionBasedOnContent; const DefinedAtom::Interposable KeyValues::interposableDefault = DefinedAtom::interposeNo; const DefinedAtom::Merge KeyValues::mergeDefault = DefinedAtom::mergeNo; const DefinedAtom::ContentPermissions KeyValues::permissionsDefault = DefinedAtom::permR__; const bool KeyValues::isThumbDefault = false; const bool KeyValues::isAliasDefault = false; const UndefinedAtom::CanBeNull KeyValues::canBeNullDefault = UndefinedAtom::canBeNullNever; const File::Kind KeyValues::fileKindDefault = File::kindObject; struct FileKindMapping { const char* string; File::Kind value; }; static const FileKindMapping fileKindMappings[] = { { "object", File::kindObject }, { "archive", File::kindArchiveLibrary }, { "shared-library", File::kindSharedLibrary }, { nullptr, File::kindObject } }; File::Kind KeyValues::fileKind(StringRef str) { for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) { if (str == p->string) return p->value; } llvm::report_fatal_error("bad file kind value"); } const char* KeyValues::fileKind(File::Kind k) { for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) { if ( p->value == k ) return p->string; } llvm::report_fatal_error("bad file kind value"); } struct DefinitionMapping { const char* string; Atom::Definition value; }; static const DefinitionMapping defMappings[] = { { "regular", Atom::definitionRegular }, { "absolute", Atom::definitionAbsolute }, { "undefined", Atom::definitionUndefined }, { "shared-library", Atom::definitionSharedLibrary }, { nullptr, Atom::definitionRegular } }; Atom::Definition KeyValues::definition(StringRef s) { for (const DefinitionMapping* p = defMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad definition value"); } const char* KeyValues::definition(Atom::Definition s) { for (const DefinitionMapping* p = defMappings; p->string != nullptr; ++p) { if ( p->value == s ) return p->string; } llvm::report_fatal_error("bad definition value"); } struct ScopeMapping { const char* string; DefinedAtom::Scope value; }; static const ScopeMapping scopeMappings[] = { { "global", DefinedAtom::scopeGlobal }, { "hidden", DefinedAtom::scopeLinkageUnit }, { "static", DefinedAtom::scopeTranslationUnit }, { nullptr, DefinedAtom::scopeGlobal } }; DefinedAtom::Scope KeyValues::scope(StringRef s) { for (const ScopeMapping* p = scopeMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad scope value"); } const char* KeyValues::scope(DefinedAtom::Scope s) { for (const ScopeMapping* p = scopeMappings; p->string != nullptr; ++p) { if ( p->value == s ) return p->string; } llvm::report_fatal_error("bad scope value"); } struct ContentTypeMapping { const char* string; DefinedAtom::ContentType value; }; static const ContentTypeMapping typeMappings[] = { { "unknown", DefinedAtom::typeUnknown }, { "code", DefinedAtom::typeCode }, { "stub", DefinedAtom::typeStub }, { "stub-helper", DefinedAtom::typeStubHelper }, { "resolver", DefinedAtom::typeResolver }, { "constant", DefinedAtom::typeConstant }, { "c-string", DefinedAtom::typeCString }, { "utf16-string", DefinedAtom::typeUTF16String }, { "CFI", DefinedAtom::typeCFI }, { "LSDA", DefinedAtom::typeLSDA }, { "literal-4", DefinedAtom::typeLiteral4 }, { "literal-8", DefinedAtom::typeLiteral8 }, { "literal-16", DefinedAtom::typeLiteral16 }, { "data", DefinedAtom::typeData }, { "zero-fill", DefinedAtom::typeZeroFill }, { "cf-string", DefinedAtom::typeCFString }, { "got", DefinedAtom::typeGOT }, { "lazy-pointer", DefinedAtom::typeLazyPointer }, { "initializer-ptr",DefinedAtom::typeInitializerPtr }, { "terminator-ptr", DefinedAtom::typeTerminatorPtr }, { "c-string-ptr", DefinedAtom::typeCStringPtr }, { "objc1-class", DefinedAtom::typeObjC1Class }, { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr }, { "objc2-cat-ptr", DefinedAtom::typeObjC2CategoryList }, { "tlv-thunk", DefinedAtom::typeThunkTLV }, { "tlv-data", DefinedAtom::typeTLVInitialData }, { "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill }, { "tlv-init-ptr", DefinedAtom::typeTLVInitializerPtr }, { nullptr, DefinedAtom::typeUnknown } }; DefinedAtom::ContentType KeyValues::contentType(StringRef s) { for (const ContentTypeMapping* p = typeMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad content type value"); } const char* KeyValues::contentType(DefinedAtom::ContentType s) { for (const ContentTypeMapping* p = typeMappings; p->string != nullptr; ++p) { if ( p->value == s ) return p->string; } llvm::report_fatal_error("bad content type value"); } struct DeadStripMapping { const char* string; DefinedAtom::DeadStripKind value; }; static const DeadStripMapping deadStripMappings[] = { { "normal", DefinedAtom::deadStripNormal }, { "never", DefinedAtom::deadStripNever }, { "always", DefinedAtom::deadStripAlways }, { nullptr, DefinedAtom::deadStripNormal } }; DefinedAtom::DeadStripKind KeyValues::deadStripKind(StringRef s) { for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad dead strip value"); } const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) { for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p) { if ( p->value == dsk ) return p->string; } llvm::report_fatal_error("bad dead strip value"); } struct InterposableMapping { const char* string; DefinedAtom::Interposable value; }; static const InterposableMapping interMappings[] = { { "no", DefinedAtom::interposeNo }, { "yes", DefinedAtom::interposeYes }, { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak }, { nullptr, DefinedAtom::interposeNo } }; DefinedAtom::Interposable KeyValues::interposable(StringRef s) { for (const InterposableMapping* p = interMappings; p->string != nullptr; ++p){ if (s == p->string) return p->value; } llvm::report_fatal_error("bad interposable value"); } const char* KeyValues::interposable(DefinedAtom::Interposable in) { for (const InterposableMapping* p = interMappings; p->string != nullptr; ++p){ if ( p->value == in ) return p->string; } llvm::report_fatal_error("bad interposable value"); } struct MergeMapping { const char* string; DefinedAtom::Merge value; }; static const MergeMapping mergeMappings[] = { { "no", DefinedAtom::mergeNo }, { "asTentative", DefinedAtom::mergeAsTentative }, { "asWeak", DefinedAtom::mergeAsWeak }, { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed }, { nullptr, DefinedAtom::mergeNo } }; DefinedAtom::Merge KeyValues::merge(StringRef s) { for (const MergeMapping* p = mergeMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad merge value"); } const char* KeyValues::merge(DefinedAtom::Merge in) { for (const MergeMapping* p = mergeMappings; p->string != nullptr; ++p) { if ( p->value == in ) return p->string; } llvm::report_fatal_error("bad merge value"); } struct SectionChoiceMapping { const char* string; DefinedAtom::SectionChoice value; }; static const SectionChoiceMapping sectMappings[] = { { "content", DefinedAtom::sectionBasedOnContent }, { "custom", DefinedAtom::sectionCustomPreferred }, { "custom-required", DefinedAtom::sectionCustomRequired }, { nullptr, DefinedAtom::sectionBasedOnContent } }; DefinedAtom::SectionChoice KeyValues::sectionChoice(StringRef s) { for (const SectionChoiceMapping* p = sectMappings; p->string != nullptr; ++p){ if (s == p->string) return p->value; } llvm::report_fatal_error("bad dead strip value"); } const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) { for (const SectionChoiceMapping* p = sectMappings; p->string != nullptr; ++p){ if ( p->value == s ) return p->string; } llvm::report_fatal_error("bad dead strip value"); } struct PermissionsMapping { const char* string; DefinedAtom::ContentPermissions value; }; static const PermissionsMapping permMappings[] = { { "content", DefinedAtom::perm___ }, { "custom", DefinedAtom::permR__ }, { "custom-required", DefinedAtom::permR_X }, { "custom-required", DefinedAtom::permRW_ }, { "custom-required", DefinedAtom::permRW_L }, { nullptr, DefinedAtom::perm___ } }; DefinedAtom::ContentPermissions KeyValues::permissions(StringRef s) { for (const PermissionsMapping* p = permMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad permissions value"); } const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) { for (const PermissionsMapping* p = permMappings; p->string != nullptr; ++p) { if ( p->value == s ) return p->string; } llvm::report_fatal_error("bad permissions value"); } const char* KeyValues::isThumb(bool b) { return b ? "true" : "false"; } const char* KeyValues::isAlias(bool b) { return b ? "true" : "false"; } struct CanBeNullMapping { const char* string; UndefinedAtom::CanBeNull value; }; static const CanBeNullMapping cbnMappings[] = { { "never", UndefinedAtom::canBeNullNever }, { "at-runtime", UndefinedAtom::canBeNullAtRuntime }, { "at-buildtime", UndefinedAtom::canBeNullAtBuildtime }, { nullptr, UndefinedAtom::canBeNullNever } }; UndefinedAtom::CanBeNull KeyValues::canBeNull(StringRef s) { for (const CanBeNullMapping* p = cbnMappings; p->string != nullptr; ++p) { if (s == p->string) return p->value; } llvm::report_fatal_error("bad can-be-null value"); } const char* KeyValues::canBeNull(UndefinedAtom::CanBeNull c) { for (const CanBeNullMapping* p = cbnMappings; p->string != nullptr; ++p) { if ( p->value == c ) return p->string; } llvm::report_fatal_error("bad can-be-null value"); } } // namespace yaml } // namespace lld