diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp')
| -rw-r--r-- | gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 843 |
1 files changed, 0 insertions, 843 deletions
diff --git a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp deleted file mode 100644 index 92a646dab5e..00000000000 --- a/gnu/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ /dev/null @@ -1,843 +0,0 @@ -//===- lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp -----------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -/// -/// \file For mach-o object files, this implementation uses YAML I/O to -/// provide the convert between YAML and the normalized mach-o (NM). -/// -/// +------------+ +------+ -/// | normalized | <-> | yaml | -/// +------------+ +------+ - -#include "MachONormalizedFile.h" -#include "lld/Common/LLVM.h" -#include "lld/Core/Error.h" -#include "lld/ReaderWriter/YamlContext.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Twine.h" -#include "llvm/BinaryFormat/MachO.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/YAMLTraits.h" -#include "llvm/Support/raw_ostream.h" -#include <system_error> - -using llvm::StringRef; -using namespace llvm::yaml; -using namespace llvm::MachO; -using namespace lld::mach_o::normalized; -using lld::YamlContext; - -LLVM_YAML_IS_SEQUENCE_VECTOR(Segment) -LLVM_YAML_IS_SEQUENCE_VECTOR(DependentDylib) -LLVM_YAML_IS_SEQUENCE_VECTOR(RebaseLocation) -LLVM_YAML_IS_SEQUENCE_VECTOR(BindLocation) -LLVM_YAML_IS_SEQUENCE_VECTOR(Export) -LLVM_YAML_IS_SEQUENCE_VECTOR(DataInCode) - - -// for compatibility with gcc-4.7 in C++11 mode, add extra namespace -namespace llvm { -namespace yaml { - -// A vector of Sections is a sequence. -template<> -struct SequenceTraits< std::vector<Section> > { - static size_t size(IO &io, std::vector<Section> &seq) { - return seq.size(); - } - static Section& element(IO &io, std::vector<Section> &seq, size_t index) { - if ( index >= seq.size() ) - seq.resize(index+1); - return seq[index]; - } -}; - -template<> -struct SequenceTraits< std::vector<Symbol> > { - static size_t size(IO &io, std::vector<Symbol> &seq) { - return seq.size(); - } - static Symbol& element(IO &io, std::vector<Symbol> &seq, size_t index) { - if ( index >= seq.size() ) - seq.resize(index+1); - return seq[index]; - } -}; - -// A vector of Relocations is a sequence. -template<> -struct SequenceTraits< Relocations > { - static size_t size(IO &io, Relocations &seq) { - return seq.size(); - } - static Relocation& element(IO &io, Relocations &seq, size_t index) { - if ( index >= seq.size() ) - seq.resize(index+1); - return seq[index]; - } -}; - -// The content for a section is represented as a flow sequence of hex bytes. -template<> -struct SequenceTraits< ContentBytes > { - static size_t size(IO &io, ContentBytes &seq) { - return seq.size(); - } - static Hex8& element(IO &io, ContentBytes &seq, size_t index) { - if ( index >= seq.size() ) - seq.resize(index+1); - return seq[index]; - } - static const bool flow = true; -}; - -// The indirect symbols for a section is represented as a flow sequence -// of numbers (symbol table indexes). -template<> -struct SequenceTraits< IndirectSymbols > { - static size_t size(IO &io, IndirectSymbols &seq) { - return seq.size(); - } - static uint32_t& element(IO &io, IndirectSymbols &seq, size_t index) { - if ( index >= seq.size() ) - seq.resize(index+1); - return seq[index]; - } - static const bool flow = true; -}; - -template <> -struct ScalarEnumerationTraits<lld::MachOLinkingContext::Arch> { - static void enumeration(IO &io, lld::MachOLinkingContext::Arch &value) { - io.enumCase(value, "unknown",lld::MachOLinkingContext::arch_unknown); - io.enumCase(value, "ppc", lld::MachOLinkingContext::arch_ppc); - io.enumCase(value, "x86", lld::MachOLinkingContext::arch_x86); - io.enumCase(value, "x86_64", lld::MachOLinkingContext::arch_x86_64); - io.enumCase(value, "armv6", lld::MachOLinkingContext::arch_armv6); - io.enumCase(value, "armv7", lld::MachOLinkingContext::arch_armv7); - io.enumCase(value, "armv7s", lld::MachOLinkingContext::arch_armv7s); - io.enumCase(value, "arm64", lld::MachOLinkingContext::arch_arm64); - } -}; - -template <> -struct ScalarEnumerationTraits<lld::MachOLinkingContext::OS> { - static void enumeration(IO &io, lld::MachOLinkingContext::OS &value) { - io.enumCase(value, "unknown", - lld::MachOLinkingContext::OS::unknown); - io.enumCase(value, "Mac OS X", - lld::MachOLinkingContext::OS::macOSX); - io.enumCase(value, "iOS", - lld::MachOLinkingContext::OS::iOS); - io.enumCase(value, "iOS Simulator", - lld::MachOLinkingContext::OS::iOS_simulator); - } -}; - - -template <> -struct ScalarEnumerationTraits<HeaderFileType> { - static void enumeration(IO &io, HeaderFileType &value) { - io.enumCase(value, "MH_OBJECT", llvm::MachO::MH_OBJECT); - io.enumCase(value, "MH_DYLIB", llvm::MachO::MH_DYLIB); - io.enumCase(value, "MH_EXECUTE", llvm::MachO::MH_EXECUTE); - io.enumCase(value, "MH_BUNDLE", llvm::MachO::MH_BUNDLE); - } -}; - - -template <> -struct ScalarBitSetTraits<FileFlags> { - static void bitset(IO &io, FileFlags &value) { - io.bitSetCase(value, "MH_TWOLEVEL", - llvm::MachO::MH_TWOLEVEL); - io.bitSetCase(value, "MH_SUBSECTIONS_VIA_SYMBOLS", - llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS); - } -}; - - -template <> -struct ScalarEnumerationTraits<SectionType> { - static void enumeration(IO &io, SectionType &value) { - io.enumCase(value, "S_REGULAR", - llvm::MachO::S_REGULAR); - io.enumCase(value, "S_ZEROFILL", - llvm::MachO::S_ZEROFILL); - io.enumCase(value, "S_CSTRING_LITERALS", - llvm::MachO::S_CSTRING_LITERALS); - io.enumCase(value, "S_4BYTE_LITERALS", - llvm::MachO::S_4BYTE_LITERALS); - io.enumCase(value, "S_8BYTE_LITERALS", - llvm::MachO::S_8BYTE_LITERALS); - io.enumCase(value, "S_LITERAL_POINTERS", - llvm::MachO::S_LITERAL_POINTERS); - io.enumCase(value, "S_NON_LAZY_SYMBOL_POINTERS", - llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS); - io.enumCase(value, "S_LAZY_SYMBOL_POINTERS", - llvm::MachO::S_LAZY_SYMBOL_POINTERS); - io.enumCase(value, "S_SYMBOL_STUBS", - llvm::MachO::S_SYMBOL_STUBS); - io.enumCase(value, "S_MOD_INIT_FUNC_POINTERS", - llvm::MachO::S_MOD_INIT_FUNC_POINTERS); - io.enumCase(value, "S_MOD_TERM_FUNC_POINTERS", - llvm::MachO::S_MOD_TERM_FUNC_POINTERS); - io.enumCase(value, "S_COALESCED", - llvm::MachO::S_COALESCED); - io.enumCase(value, "S_GB_ZEROFILL", - llvm::MachO::S_GB_ZEROFILL); - io.enumCase(value, "S_INTERPOSING", - llvm::MachO::S_INTERPOSING); - io.enumCase(value, "S_16BYTE_LITERALS", - llvm::MachO::S_16BYTE_LITERALS); - io.enumCase(value, "S_DTRACE_DOF", - llvm::MachO::S_DTRACE_DOF); - io.enumCase(value, "S_LAZY_DYLIB_SYMBOL_POINTERS", - llvm::MachO::S_LAZY_DYLIB_SYMBOL_POINTERS); - io.enumCase(value, "S_THREAD_LOCAL_REGULAR", - llvm::MachO::S_THREAD_LOCAL_REGULAR); - io.enumCase(value, "S_THREAD_LOCAL_ZEROFILL", - llvm::MachO::S_THREAD_LOCAL_ZEROFILL); - io.enumCase(value, "S_THREAD_LOCAL_VARIABLES", - llvm::MachO::S_THREAD_LOCAL_VARIABLES); - io.enumCase(value, "S_THREAD_LOCAL_VARIABLE_POINTERS", - llvm::MachO::S_THREAD_LOCAL_VARIABLE_POINTERS); - io.enumCase(value, "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS", - llvm::MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); - } -}; - -template <> -struct ScalarBitSetTraits<SectionAttr> { - static void bitset(IO &io, SectionAttr &value) { - io.bitSetCase(value, "S_ATTR_PURE_INSTRUCTIONS", - llvm::MachO::S_ATTR_PURE_INSTRUCTIONS); - io.bitSetCase(value, "S_ATTR_SOME_INSTRUCTIONS", - llvm::MachO::S_ATTR_SOME_INSTRUCTIONS); - io.bitSetCase(value, "S_ATTR_NO_DEAD_STRIP", - llvm::MachO::S_ATTR_NO_DEAD_STRIP); - io.bitSetCase(value, "S_ATTR_EXT_RELOC", - llvm::MachO::S_ATTR_EXT_RELOC); - io.bitSetCase(value, "S_ATTR_LOC_RELOC", - llvm::MachO::S_ATTR_LOC_RELOC); - io.bitSetCase(value, "S_ATTR_DEBUG", - llvm::MachO::S_ATTR_DEBUG); - } -}; - -/// This is a custom formatter for SectionAlignment. Values are -/// the power to raise by, ie, the n in 2^n. -template <> struct ScalarTraits<SectionAlignment> { - static void output(const SectionAlignment &value, void *ctxt, - raw_ostream &out) { - out << llvm::format("%d", (uint32_t)value); - } - - static StringRef input(StringRef scalar, void *ctxt, - SectionAlignment &value) { - uint32_t alignment; - if (scalar.getAsInteger(0, alignment)) { - return "malformed alignment value"; - } - if (!llvm::isPowerOf2_32(alignment)) - return "alignment must be a power of 2"; - value = alignment; - return StringRef(); // returning empty string means success - } - - static QuotingType mustQuote(StringRef) { return QuotingType::None; } -}; - -template <> -struct ScalarEnumerationTraits<NListType> { - static void enumeration(IO &io, NListType &value) { - io.enumCase(value, "N_UNDF", llvm::MachO::N_UNDF); - io.enumCase(value, "N_ABS", llvm::MachO::N_ABS); - io.enumCase(value, "N_SECT", llvm::MachO::N_SECT); - io.enumCase(value, "N_PBUD", llvm::MachO::N_PBUD); - io.enumCase(value, "N_INDR", llvm::MachO::N_INDR); - } -}; - -template <> -struct ScalarBitSetTraits<SymbolScope> { - static void bitset(IO &io, SymbolScope &value) { - io.bitSetCase(value, "N_EXT", llvm::MachO::N_EXT); - io.bitSetCase(value, "N_PEXT", llvm::MachO::N_PEXT); - } -}; - -template <> -struct ScalarBitSetTraits<SymbolDesc> { - static void bitset(IO &io, SymbolDesc &value) { - io.bitSetCase(value, "N_NO_DEAD_STRIP", llvm::MachO::N_NO_DEAD_STRIP); - io.bitSetCase(value, "N_WEAK_REF", llvm::MachO::N_WEAK_REF); - io.bitSetCase(value, "N_WEAK_DEF", llvm::MachO::N_WEAK_DEF); - io.bitSetCase(value, "N_ARM_THUMB_DEF", llvm::MachO::N_ARM_THUMB_DEF); - io.bitSetCase(value, "N_SYMBOL_RESOLVER", llvm::MachO::N_SYMBOL_RESOLVER); - } -}; - - -template <> -struct MappingTraits<Section> { - struct NormalizedContentBytes; - static void mapping(IO &io, Section §) { - io.mapRequired("segment", sect.segmentName); - io.mapRequired("section", sect.sectionName); - io.mapRequired("type", sect.type); - io.mapOptional("attributes", sect.attributes); - io.mapOptional("alignment", sect.alignment, (SectionAlignment)1); - io.mapRequired("address", sect.address); - if (isZeroFillSection(sect.type)) { - // S_ZEROFILL sections use "size:" instead of "content:" - uint64_t size = sect.content.size(); - io.mapOptional("size", size); - if (!io.outputting()) { - uint8_t *bytes = nullptr; - sect.content = makeArrayRef(bytes, size); - } - } else { - MappingNormalization<NormalizedContent, ArrayRef<uint8_t>> content( - io, sect.content); - io.mapOptional("content", content->_normalizedContent); - } - io.mapOptional("relocations", sect.relocations); - io.mapOptional("indirect-syms", sect.indirectSymbols); - } - - struct NormalizedContent { - NormalizedContent(IO &io) : _io(io) {} - NormalizedContent(IO &io, ArrayRef<uint8_t> content) : _io(io) { - // When writing yaml, copy content byte array to Hex8 vector. - for (auto &c : content) { - _normalizedContent.push_back(c); - } - } - ArrayRef<uint8_t> denormalize(IO &io) { - // When reading yaml, allocate byte array owned by NormalizedFile and - // copy Hex8 vector to byte array. - YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext()); - assert(info != nullptr); - NormalizedFile *file = info->_normalizeMachOFile; - assert(file != nullptr); - size_t size = _normalizedContent.size(); - if (!size) - return None; - uint8_t *bytes = file->ownedAllocations.Allocate<uint8_t>(size); - std::copy(_normalizedContent.begin(), _normalizedContent.end(), bytes); - return makeArrayRef(bytes, size); - } - - IO &_io; - ContentBytes _normalizedContent; - }; -}; - - -template <> -struct MappingTraits<Relocation> { - static void mapping(IO &io, Relocation &reloc) { - io.mapRequired("offset", reloc.offset); - io.mapOptional("scattered", reloc.scattered, false); - io.mapRequired("type", reloc.type); - io.mapRequired("length", reloc.length); - io.mapRequired("pc-rel", reloc.pcRel); - if ( !reloc.scattered ) - io.mapRequired("extern", reloc.isExtern); - if ( reloc.scattered ) - io.mapRequired("value", reloc.value); - if ( !reloc.scattered ) - io.mapRequired("symbol", reloc.symbol); - } -}; - - -template <> -struct ScalarEnumerationTraits<RelocationInfoType> { - static void enumeration(IO &io, RelocationInfoType &value) { - YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext()); - assert(info != nullptr); - NormalizedFile *file = info->_normalizeMachOFile; - assert(file != nullptr); - switch (file->arch) { - case lld::MachOLinkingContext::arch_x86_64: - io.enumCase(value, "X86_64_RELOC_UNSIGNED", - llvm::MachO::X86_64_RELOC_UNSIGNED); - io.enumCase(value, "X86_64_RELOC_SIGNED", - llvm::MachO::X86_64_RELOC_SIGNED); - io.enumCase(value, "X86_64_RELOC_BRANCH", - llvm::MachO::X86_64_RELOC_BRANCH); - io.enumCase(value, "X86_64_RELOC_GOT_LOAD", - llvm::MachO::X86_64_RELOC_GOT_LOAD); - io.enumCase(value, "X86_64_RELOC_GOT", - llvm::MachO::X86_64_RELOC_GOT); - io.enumCase(value, "X86_64_RELOC_SUBTRACTOR", - llvm::MachO::X86_64_RELOC_SUBTRACTOR); - io.enumCase(value, "X86_64_RELOC_SIGNED_1", - llvm::MachO::X86_64_RELOC_SIGNED_1); - io.enumCase(value, "X86_64_RELOC_SIGNED_2", - llvm::MachO::X86_64_RELOC_SIGNED_2); - io.enumCase(value, "X86_64_RELOC_SIGNED_4", - llvm::MachO::X86_64_RELOC_SIGNED_4); - io.enumCase(value, "X86_64_RELOC_TLV", - llvm::MachO::X86_64_RELOC_TLV); - break; - case lld::MachOLinkingContext::arch_x86: - io.enumCase(value, "GENERIC_RELOC_VANILLA", - llvm::MachO::GENERIC_RELOC_VANILLA); - io.enumCase(value, "GENERIC_RELOC_PAIR", - llvm::MachO::GENERIC_RELOC_PAIR); - io.enumCase(value, "GENERIC_RELOC_SECTDIFF", - llvm::MachO::GENERIC_RELOC_SECTDIFF); - io.enumCase(value, "GENERIC_RELOC_LOCAL_SECTDIFF", - llvm::MachO::GENERIC_RELOC_LOCAL_SECTDIFF); - io.enumCase(value, "GENERIC_RELOC_TLV", - llvm::MachO::GENERIC_RELOC_TLV); - break; - case lld::MachOLinkingContext::arch_armv6: - case lld::MachOLinkingContext::arch_armv7: - case lld::MachOLinkingContext::arch_armv7s: - io.enumCase(value, "ARM_RELOC_VANILLA", - llvm::MachO::ARM_RELOC_VANILLA); - io.enumCase(value, "ARM_RELOC_PAIR", - llvm::MachO::ARM_RELOC_PAIR); - io.enumCase(value, "ARM_RELOC_SECTDIFF", - llvm::MachO::ARM_RELOC_SECTDIFF); - io.enumCase(value, "ARM_RELOC_LOCAL_SECTDIFF", - llvm::MachO::ARM_RELOC_LOCAL_SECTDIFF); - io.enumCase(value, "ARM_RELOC_BR24", - llvm::MachO::ARM_RELOC_BR24); - io.enumCase(value, "ARM_THUMB_RELOC_BR22", - llvm::MachO::ARM_THUMB_RELOC_BR22); - io.enumCase(value, "ARM_RELOC_HALF", - llvm::MachO::ARM_RELOC_HALF); - io.enumCase(value, "ARM_RELOC_HALF_SECTDIFF", - llvm::MachO::ARM_RELOC_HALF_SECTDIFF); - break; - case lld::MachOLinkingContext::arch_arm64: - io.enumCase(value, "ARM64_RELOC_UNSIGNED", - llvm::MachO::ARM64_RELOC_UNSIGNED); - io.enumCase(value, "ARM64_RELOC_SUBTRACTOR", - llvm::MachO::ARM64_RELOC_SUBTRACTOR); - io.enumCase(value, "ARM64_RELOC_BRANCH26", - llvm::MachO::ARM64_RELOC_BRANCH26); - io.enumCase(value, "ARM64_RELOC_PAGE21", - llvm::MachO::ARM64_RELOC_PAGE21); - io.enumCase(value, "ARM64_RELOC_PAGEOFF12", - llvm::MachO::ARM64_RELOC_PAGEOFF12); - io.enumCase(value, "ARM64_RELOC_GOT_LOAD_PAGE21", - llvm::MachO::ARM64_RELOC_GOT_LOAD_PAGE21); - io.enumCase(value, "ARM64_RELOC_GOT_LOAD_PAGEOFF12", - llvm::MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12); - io.enumCase(value, "ARM64_RELOC_POINTER_TO_GOT", - llvm::MachO::ARM64_RELOC_POINTER_TO_GOT); - io.enumCase(value, "ARM64_RELOC_TLVP_LOAD_PAGE21", - llvm::MachO::ARM64_RELOC_TLVP_LOAD_PAGE21); - io.enumCase(value, "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", - llvm::MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12); - io.enumCase(value, "ARM64_RELOC_ADDEND", - llvm::MachO::ARM64_RELOC_ADDEND); - break; - default: - llvm_unreachable("unknown architecture"); - } - } -}; - - -template <> -struct MappingTraits<Symbol> { - static void mapping(IO &io, Symbol& sym) { - io.mapRequired("name", sym.name); - io.mapRequired("type", sym.type); - io.mapOptional("scope", sym.scope, SymbolScope(0)); - io.mapOptional("sect", sym.sect, (uint8_t)0); - if (sym.type == llvm::MachO::N_UNDF) { - // In undef symbols, desc field contains alignment/ordinal info - // which is better represented as a hex vaule. - uint16_t t1 = sym.desc; - Hex16 t2 = t1; - io.mapOptional("desc", t2, Hex16(0)); - sym.desc = t2; - } else { - // In defined symbols, desc fit is a set of option bits. - io.mapOptional("desc", sym.desc, SymbolDesc(0)); - } - io.mapRequired("value", sym.value); - } -}; - -// Custom mapping for VMProtect (e.g. "r-x"). -template <> -struct ScalarTraits<VMProtect> { - static void output(const VMProtect &value, void*, raw_ostream &out) { - out << ( (value & llvm::MachO::VM_PROT_READ) ? 'r' : '-'); - out << ( (value & llvm::MachO::VM_PROT_WRITE) ? 'w' : '-'); - out << ( (value & llvm::MachO::VM_PROT_EXECUTE) ? 'x' : '-'); - } - static StringRef input(StringRef scalar, void*, VMProtect &value) { - value = 0; - if (scalar.size() != 3) - return "segment access protection must be three chars (e.g. \"r-x\")"; - switch (scalar[0]) { - case 'r': - value = llvm::MachO::VM_PROT_READ; - break; - case '-': - break; - default: - return "segment access protection first char must be 'r' or '-'"; - } - switch (scalar[1]) { - case 'w': - value = value | llvm::MachO::VM_PROT_WRITE; - break; - case '-': - break; - default: - return "segment access protection second char must be 'w' or '-'"; - } - switch (scalar[2]) { - case 'x': - value = value | llvm::MachO::VM_PROT_EXECUTE; - break; - case '-': - break; - default: - return "segment access protection third char must be 'x' or '-'"; - } - // Return the empty string on success, - return StringRef(); - } - static QuotingType mustQuote(StringRef) { return QuotingType::None; } -}; - - -template <> -struct MappingTraits<Segment> { - static void mapping(IO &io, Segment& seg) { - io.mapRequired("name", seg.name); - io.mapRequired("address", seg.address); - io.mapRequired("size", seg.size); - io.mapRequired("init-access", seg.init_access); - io.mapRequired("max-access", seg.max_access); - } -}; - -template <> -struct ScalarEnumerationTraits<LoadCommandType> { - static void enumeration(IO &io, LoadCommandType &value) { - io.enumCase(value, "LC_LOAD_DYLIB", - llvm::MachO::LC_LOAD_DYLIB); - io.enumCase(value, "LC_LOAD_WEAK_DYLIB", - llvm::MachO::LC_LOAD_WEAK_DYLIB); - io.enumCase(value, "LC_REEXPORT_DYLIB", - llvm::MachO::LC_REEXPORT_DYLIB); - io.enumCase(value, "LC_LOAD_UPWARD_DYLIB", - llvm::MachO::LC_LOAD_UPWARD_DYLIB); - io.enumCase(value, "LC_LAZY_LOAD_DYLIB", - llvm::MachO::LC_LAZY_LOAD_DYLIB); - io.enumCase(value, "LC_VERSION_MIN_MACOSX", - llvm::MachO::LC_VERSION_MIN_MACOSX); - io.enumCase(value, "LC_VERSION_MIN_IPHONEOS", - llvm::MachO::LC_VERSION_MIN_IPHONEOS); - io.enumCase(value, "LC_VERSION_MIN_TVOS", - llvm::MachO::LC_VERSION_MIN_TVOS); - io.enumCase(value, "LC_VERSION_MIN_WATCHOS", - llvm::MachO::LC_VERSION_MIN_WATCHOS); - } -}; - -template <> -struct MappingTraits<DependentDylib> { - static void mapping(IO &io, DependentDylib& dylib) { - io.mapRequired("path", dylib.path); - io.mapOptional("kind", dylib.kind, - llvm::MachO::LC_LOAD_DYLIB); - io.mapOptional("compat-version", dylib.compatVersion, - PackedVersion(0x10000)); - io.mapOptional("current-version", dylib.currentVersion, - PackedVersion(0x10000)); - } -}; - -template <> -struct ScalarEnumerationTraits<RebaseType> { - static void enumeration(IO &io, RebaseType &value) { - io.enumCase(value, "REBASE_TYPE_POINTER", - llvm::MachO::REBASE_TYPE_POINTER); - io.enumCase(value, "REBASE_TYPE_TEXT_PCREL32", - llvm::MachO::REBASE_TYPE_TEXT_PCREL32); - io.enumCase(value, "REBASE_TYPE_TEXT_ABSOLUTE32", - llvm::MachO::REBASE_TYPE_TEXT_ABSOLUTE32); - } -}; - - -template <> -struct MappingTraits<RebaseLocation> { - static void mapping(IO &io, RebaseLocation& rebase) { - io.mapRequired("segment-index", rebase.segIndex); - io.mapRequired("segment-offset", rebase.segOffset); - io.mapOptional("kind", rebase.kind, - llvm::MachO::REBASE_TYPE_POINTER); - } -}; - - - -template <> -struct ScalarEnumerationTraits<BindType> { - static void enumeration(IO &io, BindType &value) { - io.enumCase(value, "BIND_TYPE_POINTER", - llvm::MachO::BIND_TYPE_POINTER); - io.enumCase(value, "BIND_TYPE_TEXT_ABSOLUTE32", - llvm::MachO::BIND_TYPE_TEXT_ABSOLUTE32); - io.enumCase(value, "BIND_TYPE_TEXT_PCREL32", - llvm::MachO::BIND_TYPE_TEXT_PCREL32); - } -}; - -template <> -struct MappingTraits<BindLocation> { - static void mapping(IO &io, BindLocation &bind) { - io.mapRequired("segment-index", bind.segIndex); - io.mapRequired("segment-offset", bind.segOffset); - io.mapOptional("kind", bind.kind, - llvm::MachO::BIND_TYPE_POINTER); - io.mapOptional("can-be-null", bind.canBeNull, false); - io.mapRequired("ordinal", bind.ordinal); - io.mapRequired("symbol-name", bind.symbolName); - io.mapOptional("addend", bind.addend, Hex64(0)); - } -}; - - -template <> -struct ScalarEnumerationTraits<ExportSymbolKind> { - static void enumeration(IO &io, ExportSymbolKind &value) { - io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_REGULAR", - llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR); - io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL", - llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL); - io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE", - llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE); - } -}; - -template <> -struct ScalarBitSetTraits<ExportFlags> { - static void bitset(IO &io, ExportFlags &value) { - io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION", - llvm::MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION); - io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_REEXPORT", - llvm::MachO::EXPORT_SYMBOL_FLAGS_REEXPORT); - io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER", - llvm::MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER); - } -}; - - -template <> -struct MappingTraits<Export> { - static void mapping(IO &io, Export &exp) { - io.mapRequired("name", exp.name); - io.mapOptional("offset", exp.offset); - io.mapOptional("kind", exp.kind, - llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR); - if (!io.outputting() || exp.flags) - io.mapOptional("flags", exp.flags); - io.mapOptional("other", exp.otherOffset, Hex32(0)); - io.mapOptional("other-name", exp.otherName, StringRef()); - } -}; - -template <> -struct ScalarEnumerationTraits<DataRegionType> { - static void enumeration(IO &io, DataRegionType &value) { - io.enumCase(value, "DICE_KIND_DATA", - llvm::MachO::DICE_KIND_DATA); - io.enumCase(value, "DICE_KIND_JUMP_TABLE8", - llvm::MachO::DICE_KIND_JUMP_TABLE8); - io.enumCase(value, "DICE_KIND_JUMP_TABLE16", - llvm::MachO::DICE_KIND_JUMP_TABLE16); - io.enumCase(value, "DICE_KIND_JUMP_TABLE32", - llvm::MachO::DICE_KIND_JUMP_TABLE32); - io.enumCase(value, "DICE_KIND_ABS_JUMP_TABLE32", - llvm::MachO::DICE_KIND_ABS_JUMP_TABLE32); - } -}; - -template <> -struct MappingTraits<DataInCode> { - static void mapping(IO &io, DataInCode &entry) { - io.mapRequired("offset", entry.offset); - io.mapRequired("length", entry.length); - io.mapRequired("kind", entry.kind); - } -}; - -template <> -struct ScalarTraits<PackedVersion> { - static void output(const PackedVersion &value, void*, raw_ostream &out) { - out << llvm::format("%d.%d", (value >> 16), (value >> 8) & 0xFF); - if (value & 0xFF) { - out << llvm::format(".%d", (value & 0xFF)); - } - } - static StringRef input(StringRef scalar, void*, PackedVersion &result) { - uint32_t value; - if (lld::MachOLinkingContext::parsePackedVersion(scalar, value)) - return "malformed version number"; - result = value; - // Return the empty string on success, - return StringRef(); - } - static QuotingType mustQuote(StringRef) { return QuotingType::None; } -}; - -template <> -struct MappingTraits<NormalizedFile> { - static void mapping(IO &io, NormalizedFile &file) { - io.mapRequired("arch", file.arch); - io.mapRequired("file-type", file.fileType); - io.mapOptional("flags", file.flags); - io.mapOptional("dependents", file.dependentDylibs); - io.mapOptional("install-name", file.installName, StringRef()); - io.mapOptional("compat-version", file.compatVersion, PackedVersion(0x10000)); - io.mapOptional("current-version", file.currentVersion, PackedVersion(0x10000)); - io.mapOptional("has-UUID", file.hasUUID, true); - io.mapOptional("rpaths", file.rpaths); - io.mapOptional("entry-point", file.entryAddress, Hex64(0)); - io.mapOptional("stack-size", file.stackSize, Hex64(0)); - io.mapOptional("source-version", file.sourceVersion, Hex64(0)); - io.mapOptional("OS", file.os); - io.mapOptional("min-os-version", file.minOSverson, PackedVersion(0)); - io.mapOptional("min-os-version-kind", file.minOSVersionKind, (LoadCommandType)0); - io.mapOptional("sdk-version", file.sdkVersion, PackedVersion(0)); - io.mapOptional("segments", file.segments); - io.mapOptional("sections", file.sections); - io.mapOptional("local-symbols", file.localSymbols); - io.mapOptional("global-symbols", file.globalSymbols); - io.mapOptional("undefined-symbols",file.undefinedSymbols); - io.mapOptional("page-size", file.pageSize, Hex32(4096)); - io.mapOptional("rebasings", file.rebasingInfo); - io.mapOptional("bindings", file.bindingInfo); - io.mapOptional("weak-bindings", file.weakBindingInfo); - io.mapOptional("lazy-bindings", file.lazyBindingInfo); - io.mapOptional("exports", file.exportInfo); - io.mapOptional("dataInCode", file.dataInCode); - } - static StringRef validate(IO &io, NormalizedFile &file) { - return StringRef(); - } -}; - -} // namespace llvm -} // namespace yaml - - -namespace lld { -namespace mach_o { - -/// Handles !mach-o tagged yaml documents. -bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io, - const lld::File *&file) const { - if (!io.mapTag("!mach-o")) - return false; - // Step 1: parse yaml into normalized mach-o struct. - NormalizedFile nf; - YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext()); - assert(info != nullptr); - assert(info->_normalizeMachOFile == nullptr); - info->_normalizeMachOFile = &nf; - MappingTraits<NormalizedFile>::mapping(io, nf); - // Step 2: parse normalized mach-o struct into atoms. - auto fileOrError = normalizedToAtoms(nf, info->_path, true); - - // Check that we parsed successfully. - if (!fileOrError) { - std::string buffer; - llvm::raw_string_ostream stream(buffer); - handleAllErrors(fileOrError.takeError(), - [&](const llvm::ErrorInfoBase &EI) { - EI.log(stream); - stream << "\n"; - }); - io.setError(stream.str()); - return false; - } - - if (nf.arch != _arch) { - io.setError(Twine("file is wrong architecture. Expected (" - + MachOLinkingContext::nameFromArch(_arch) - + ") found (" - + MachOLinkingContext::nameFromArch(nf.arch) - + ")")); - return false; - } - info->_normalizeMachOFile = nullptr; - file = fileOrError->release(); - return true; -} - - - -namespace normalized { - -/// Parses a yaml encoded mach-o file to produce an in-memory normalized view. -llvm::Expected<std::unique_ptr<NormalizedFile>> -readYaml(std::unique_ptr<MemoryBuffer> &mb) { - // Make empty NormalizedFile. - std::unique_ptr<NormalizedFile> f(new NormalizedFile()); - - // Create YAML Input parser. - YamlContext yamlContext; - yamlContext._normalizeMachOFile = f.get(); - llvm::yaml::Input yin(mb->getBuffer(), &yamlContext); - - // Fill NormalizedFile by parsing yaml. - yin >> *f; - - // Return error if there were parsing problems. - if (auto ec = yin.error()) - return llvm::make_error<GenericError>(Twine("YAML parsing error: ") - + ec.message()); - - // Hand ownership of instantiated NormalizedFile to caller. - return std::move(f); -} - - -/// Writes a yaml encoded mach-o files from an in-memory normalized view. -std::error_code writeYaml(const NormalizedFile &file, raw_ostream &out) { - // YAML I/O is not const aware, so need to cast away ;-( - NormalizedFile *f = const_cast<NormalizedFile*>(&file); - - // Create yaml Output writer, using yaml options for context. - YamlContext yamlContext; - yamlContext._normalizeMachOFile = f; - llvm::yaml::Output yout(out, &yamlContext); - - // Stream out yaml. - yout << *f; - - return std::error_code(); -} - -} // namespace normalized -} // namespace mach_o -} // namespace lld |
