diff options
Diffstat (limited to 'lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp')
-rw-r--r-- | lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 81 |
1 files changed, 61 insertions, 20 deletions
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index 0b92a68eeae8..66be77173983 100644 --- a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -237,6 +237,29 @@ struct ScalarBitSetTraits<SectionAttr> { } }; +/// 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 bool mustQuote(StringRef) { return false; } +}; + template <> struct ScalarEnumerationTraits<NListType> { static void enumeration(IO &io, NListType &value) { @@ -276,7 +299,7 @@ struct MappingTraits<Section> { io.mapRequired("section", sect.sectionName); io.mapRequired("type", sect.type); io.mapOptional("attributes", sect.attributes); - io.mapOptional("alignment", sect.alignment, (uint16_t)1); + io.mapOptional("alignment", sect.alignment, (SectionAlignment)1); io.mapRequired("address", sect.address); if (isZeroFillSection(sect.type)) { // S_ZEROFILL sections use "size:" instead of "content:" @@ -311,6 +334,8 @@ struct MappingTraits<Section> { 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); @@ -504,10 +529,11 @@ struct ScalarTraits<VMProtect> { 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("access", seg.access); + 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); } }; @@ -524,6 +550,14 @@ struct ScalarEnumerationTraits<LoadCommandType> { 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); } }; @@ -692,6 +726,7 @@ struct MappingTraits<NormalizedFile> { 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); @@ -731,8 +766,21 @@ bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io, info->_normalizeMachOFile = &nf; MappingTraits<NormalizedFile>::mapping(io, nf); // Step 2: parse normalized mach-o struct into atoms. - ErrorOr<std::unique_ptr<lld::File>> foe = normalizedToAtoms(nf, info->_path, - true); + 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) @@ -742,16 +790,8 @@ bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io, return false; } info->_normalizeMachOFile = nullptr; - - if (foe) { - // Transfer ownership to "out" File parameter. - std::unique_ptr<lld::File> f = std::move(foe.get()); - file = f.release(); - return true; - } else { - io.setError(foe.getError().message()); - return false; - } + file = fileOrError->release(); + return true; } @@ -759,7 +799,7 @@ bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io, namespace normalized { /// Parses a yaml encoded mach-o file to produce an in-memory normalized view. -ErrorOr<std::unique_ptr<NormalizedFile>> +llvm::Expected<std::unique_ptr<NormalizedFile>> readYaml(std::unique_ptr<MemoryBuffer> &mb) { // Make empty NormalizedFile. std::unique_ptr<NormalizedFile> f(new NormalizedFile()); @@ -773,8 +813,9 @@ readYaml(std::unique_ptr<MemoryBuffer> &mb) { yin >> *f; // Return error if there were parsing problems. - if (yin.error()) - return make_error_code(lld::YamlReaderError::illegal_value); + 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); |