<div dir="ltr"><div>This patch seems to have broken buildbot.</div><div><br></div><a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/7967">http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/7967</a><br>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Oct 7, 2013 at 5:43 PM, Nick Kledzik <span dir="ltr"><<a href="mailto:kledzik@apple.com" target="_blank">kledzik@apple.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kledzik<br>
Date: Mon Oct  7 19:43:34 2013<br>
New Revision: 192147<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=192147&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=192147&view=rev</a><br>
Log:<br>
Supoort mach-o encoded in yaml.<br>
<br>
This is the first step in how I plan to get mach-o object files support into<br>
lld. We need to be able to test the mach-o Reader and Write on systems without<br>
a mach-o tools. Therefore, we want to support a textual way (YAML) to represent<br>
mach-o files.<br>
<br>
MachONormalizedFile.h defines an in-memory abstraction of the content of mach-o<br>
files. The in-memory data structures are always native endianess and always<br>
use 64-bit sizes. That internal data structure can then be converted to or<br>
from three different formats: 1) yaml (text) encoded mach-o, 2) binary mach-o<br>
files, 3) lld Atoms.<br>
<br>
This patch defines the internal model and uses YAML I/O to implement the<br>
conversion to and from the model to yaml. The next patch will implement<br>
the conversion from normalized to binary mach-o.<br>
<br>
This patch includes unit tests to validate the yaml conversion APIs.<br>
<br>
Added:<br>
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h<br>
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp<br>
    lld/trunk/unittests/MachOTests/<br>
    lld/trunk/unittests/MachOTests/CMakeLists.txt<br>
    lld/trunk/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp<br>
Modified:<br>
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h<br>
    lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt<br>
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp<br>
    lld/trunk/unittests/CMakeLists.txt<br>
<br>
Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=192147&r1=192146&r2=192147&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=192147&r1=192146&r2=192147&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)<br>
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Mon Oct  7 19:43:34 2013<br>
@@ -47,6 +47,7 @@ public:<br>
<br>
   enum Arch {<br>
     arch_unknown,<br>
+    arch_ppc,<br>
     arch_x86,<br>
     arch_x86_64,<br>
     arch_armv6,<br>
@@ -55,7 +56,7 @@ public:<br>
   };<br>
<br>
   enum class OS {<br>
-    macOSX, iOS, iOS_simulator<br>
+    unknown, macOSX, iOS, iOS_simulator<br>
   };<br>
<br>
   Arch arch() const { return _arch; }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=192147&r1=192146&r2=192147&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=192147&r1=192146&r2=192147&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Mon Oct  7 19:43:34 2013<br>
@@ -1,5 +1,6 @@<br>
 add_lld_library(lldMachO<br>
   MachOLinkingContext.cpp<br>
+  MachONormalizedFileYAML.cpp<br>
   ReferenceKinds.cpp<br>
   WriterMachO.cpp<br>
   )<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=192147&r1=192146&r2=192147&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=192147&r1=192146&r2=192147&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Mon Oct  7 19:43:34 2013<br>
@@ -149,20 +149,19 @@ bool MachOLinkingContext::outputTypeHasE<br>
 }<br>
<br>
 bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {<br>
+  uint32_t parsedVersion;<br>
   switch (_os) {<br>
-  case OS::macOSX: {<br>
-    uint32_t parsedVersion;<br>
+  case OS::macOSX:<br>
     if (parsePackedVersion(mac, parsedVersion))<br>
       return false;<br>
     return _osMinVersion >= parsedVersion;<br>
-  }<br>
   case OS::iOS:<br>
-  case OS::iOS_simulator: {<br>
-    uint32_t parsedVersion;<br>
+  case OS::iOS_simulator:<br>
     if (parsePackedVersion(iOS, parsedVersion))<br>
       return false;<br>
     return _osMinVersion >= parsedVersion;<br>
-  }<br>
+  case OS::unknown:<br>
+    break;<br>
   }<br>
   llvm_unreachable("target not configured for iOS or MacOSX");<br>
 }<br>
<br>
Added: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=192147&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=192147&view=auto</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (added)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Mon Oct  7 19:43:34 2013<br>
@@ -0,0 +1,279 @@<br>
+//===- lib/ReaderWriter/MachO/NormalizedFile.h ----------------------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+///<br>
+/// \file These data structures comprise the "normalized" view of<br>
+/// mach-o object files. The normalized view is an in-memory only data structure<br>
+/// which is always in native endianness and pointer size.<br>
+///<br>
+/// The normalized view easily converts to and from YAML using YAML I/O.<br>
+///<br>
+/// The normalized view converts to and from binary mach-o object files using<br>
+/// the writeBinary() and readBinary() functions.<br>
+///<br>
+/// The normalized view converts to and from lld::Atoms using the<br>
+/// normalizedToAtoms() and normalizedFromAtoms().<br>
+///<br>
+/// Overall, the conversion paths available look like:<br>
+///<br>
+///                 +---------------+<br>
+///                 | binary mach-o |<br>
+///                 +---------------+<br>
+///                        ^<br>
+///                        |<br>
+///                        v<br>
+///                  +------------+         +------+<br>
+///                  | normalized |   <->   | yaml |<br>
+///                  +------------+         +------+<br>
+///                        ^<br>
+///                        |<br>
+///                        v<br>
+///                    +-------+<br>
+///                    | Atoms |<br>
+///                    +-------+<br>
+///<br>
+<br>
+#include "lld/Core/Error.h"<br>
+#include "lld/Core/LLVM.h"<br>
+#include "lld/ReaderWriter/MachOLinkingContext.h"<br>
+<br>
+#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/Support/ErrorOr.h"<br>
+#include "llvm/Support/MachO.h"<br>
+#include "llvm/Support/YAMLTraits.h"<br>
+<br>
+#ifndef LLD_READER_WRITER_MACHO_NORMALIZED_H_<br>
+#define LLD_READER_WRITER_MACHO_NORMALIZED_H_<br>
+<br>
+using llvm::yaml::Hex64;<br>
+using llvm::yaml::Hex32;<br>
+using llvm::yaml::Hex8;<br>
+using llvm::yaml::SequenceTraits;<br>
+using llvm::MachO::HeaderFileType;<br>
+using llvm::MachO::BindType;<br>
+using llvm::MachO::RebaseType;<br>
+using llvm::MachO::NListType;<br>
+using llvm::MachO::RelocationInfoType;<br>
+using llvm::MachO::SectionType;<br>
+using llvm::MachO::LoadCommandType;<br>
+using llvm::MachO::ExportSymbolKind;<br>
+<br>
+namespace lld {<br>
+namespace mach_o {<br>
+namespace normalized {<br>
+<br>
+<br>
+/// The real mach-o relocation record is 8-bytes on disk and is<br>
+/// encoded in one of two different bit-field patterns.  This<br>
+/// normalized form has the union of all possbile fields.<br>
+struct Relocation {<br>
+  Relocation() : offset(0), scattered(false),<br>
+                 type(llvm::MachO::GENERIC_RELOC_VANILLA),<br>
+                 length(0), pcRel(false), isExtern(false), value(0),<br>
+                 symbol(0) { }<br>
+<br>
+  Hex32               offset;<br>
+  bool                scattered;<br>
+  RelocationInfoType  type;<br>
+  uint8_t             length;<br>
+  bool                pcRel;<br>
+  bool                isExtern;<br>
+  Hex32               value;<br>
+  uint32_t            symbol;<br>
+};<br>
+<br>
+/// A typedef so that YAML I/O can treat this vector as a sequence.<br>
+typedef std::vector<Relocation> Relocations;<br>
+<br>
+/// A typedef so that YAML I/O can process the raw bytes in a section.<br>
+typedef std::vector<Hex8> ContentBytes;<br>
+<br>
+/// A typedef so that YAML I/O can treat indirect symbols as a flow sequence.<br>
+typedef std::vector<uint32_t> IndirectSymbols;<br>
+<br>
+/// A typedef so that YAML I/O can encode/decode section attributes.<br>
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionAttr);<br>
+<br>
+/// Mach-O has a 32-bit and 64-bit section record.  This normalized form<br>
+/// can support either kind.<br>
+struct Section {<br>
+  Section() : type(llvm::MachO::S_REGULAR),<br>
+              attributes(0), alignment(0), address(0) { }<br>
+<br>
+  StringRef       segmentName;<br>
+  StringRef       sectionName;<br>
+  SectionType     type;<br>
+  SectionAttr     attributes;<br>
+  uint32_t        alignment;<br>
+  Hex64           address;<br>
+  ContentBytes    content;<br>
+  Relocations     relocations;<br>
+  IndirectSymbols indirectSymbols;<br>
+};<br>
+<br>
+<br>
+/// A typedef so that YAML I/O can encode/decode the scope bits of an nlist.<br>
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, SymbolScope);<br>
+<br>
+/// A typedef so that YAML I/O can encode/decode the desc bits of an nlist.<br>
+LLVM_YAML_STRONG_TYPEDEF(uint16_t, SymbolDesc);<br>
+<br>
+/// Mach-O has a 32-bit and 64-bit symbol table entry (nlist), and the symbol<br>
+/// type and scope and mixed in the same n_type field.  This normalized form<br>
+/// works for any pointer size and separates out the type and scope.<br>
+struct Symbol {<br>
+  Symbol() : type(llvm::MachO::N_UNDF), scope(0), sect(0), desc(0), value(0) { }<br>
+<br>
+  StringRef     name;<br>
+  NListType     type;<br>
+  SymbolScope   scope;<br>
+  uint8_t       sect;<br>
+  SymbolDesc    desc;<br>
+  Hex64         value;<br>
+};<br>
+<br>
+/// A typedef so that YAML I/O can (de/en)code the protection bits of a segment.<br>
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, VMProtect);<br>
+<br>
+/// Segments are only used in normalized final linked images (not in relocatable<br>
+/// object files). They specify how a range of the file is loaded.<br>
+struct Segment {<br>
+  StringRef     name;<br>
+  Hex64         address;<br>
+  Hex64         size;<br>
+  VMProtect     access;<br>
+};<br>
+<br>
+/// Only used in normalized final linked images to specify on which dylibs<br>
+/// it depends.<br>
+struct DependentDylib {<br>
+  StringRef       path;<br>
+  LoadCommandType kind;<br>
+};<br>
+<br>
+/// A normalized rebasing entry.  Only used in normalized final linked images.<br>
+struct RebaseLocation {<br>
+  Hex32         segOffset;<br>
+  uint8_t       segIndex;<br>
+  RebaseType    kind;<br>
+};<br>
+<br>
+/// A normalized binding entry.  Only used in normalized final linked images.<br>
+struct BindLocation {<br>
+  Hex32           segOffset;<br>
+  uint8_t         segIndex;<br>
+  BindType        kind;<br>
+  bool            canBeNull;<br>
+  int             ordinal;<br>
+  StringRef       symbolName;<br>
+  Hex64           addend;<br>
+};<br>
+<br>
+/// A typedef so that YAML I/O can encode/decode export flags.<br>
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportFlags);<br>
+<br>
+/// A normalized export entry.  Only used in normalized final linked images.<br>
+struct Export {<br>
+  StringRef         name;<br>
+  Hex64             offset;<br>
+  ExportSymbolKind  kind;<br>
+  ExportFlags       flags;<br>
+  Hex32             otherOffset;<br>
+  StringRef         otherName;<br>
+};<br>
+<br>
+<br>
+/// A typedef so that YAML I/O can encode/decode mach_header.flags.<br>
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, FileFlags);<br>
+<br>
+///<br>
+struct NormalizedFile {<br>
+  NormalizedFile() : arch(MachOLinkingContext::arch_unknown),<br>
+                     fileType(llvm::MachO::MH_OBJECT),<br>
+                     flags(0),<br>
+                     hasUUID(false),<br>
+                     os(MachOLinkingContext::OS::unknown) { }<br>
+<br>
+  MachOLinkingContext::Arch   arch;<br>
+  HeaderFileType              fileType;<br>
+  FileFlags                   flags;<br>
+  std::vector<Segment>        segments; // Not used in object files.<br>
+  std::vector<Section>        sections;<br>
+<br>
+  // Symbols sorted by kind.<br>
+  std::vector<Symbol>         localSymbols;<br>
+  std::vector<Symbol>         globalSymbols;<br>
+  std::vector<Symbol>         undefinedSymbols;<br>
+<br>
+  // Maps to load commands with no LINKEDIT content (final linked images only).<br>
+  std::vector<DependentDylib> dependentDylibs;<br>
+  StringRef                   installName;<br>
+  bool                        hasUUID;<br>
+  std::vector<StringRef>      rpaths;<br>
+  Hex64                       entryAddress;<br>
+  MachOLinkingContext::OS     os;<br>
+  Hex64                       sourceVersion;<br>
+  Hex32                       minOSverson;<br>
+  Hex32                       sdkVersion;<br>
+<br>
+  // Maps to load commands with LINKEDIT content (final linked images only).<br>
+  std::vector<RebaseLocation> rebasingInfo;<br>
+  std::vector<BindLocation>   bindingInfo;<br>
+  std::vector<BindLocation>   weakBindingInfo;<br>
+  std::vector<BindLocation>   lazyBindingInfo;<br>
+  std::vector<Export>         exportInfo;<br>
+<br>
+  // TODO:<br>
+  // code-signature<br>
+  // split-seg-info<br>
+  // function-starts<br>
+  // data-in-code<br>
+};<br>
+<br>
+<br>
+/// Reads a mach-o file and produces an in-memory normalized view.<br>
+ErrorOr<std::unique_ptr<NormalizedFile>><br>
+readBinary(std::unique_ptr<MemoryBuffer> &mb);<br>
+<br>
+/// Takes in-memory normalized view and writes a mach-o object file.<br>
+error_code<br>
+writeBinary(const NormalizedFile &file, StringRef path);<br>
+<br>
+size_t headerAndLoadCommandsSize(const NormalizedFile &file);<br>
+<br>
+<br>
+/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.<br>
+ErrorOr<std::unique_ptr<NormalizedFile>><br>
+readYaml(std::unique_ptr<MemoryBuffer> &mb);<br>
+<br>
+/// Writes a yaml encoded mach-o files given an in-memory normalized view.<br>
+error_code<br>
+writeYaml(const NormalizedFile &file, llvm::raw_ostream &out);<br>
+<br>
+<br>
+/// Takes in-memory normalized dylib or object and parses it into lld::File<br>
+ErrorOr<std::unique_ptr<lld::File>><br>
+normalizedToAtoms(const NormalizedFile &normalizedFile);<br>
+<br>
+/// Takes atoms and generates a normalized macho-o view.<br>
+ErrorOr<std::unique_ptr<NormalizedFile>><br>
+normalizedFromAtoms(const lld::File &atomFile, const MachOLinkingContext &ctxt);<br>
+<br>
+<br>
+<br>
+} // namespace normalized<br>
+} // namespace mach_o<br>
+} // namespace lld<br>
+<br>
+#endif // LLD_READER_WRITER_MACHO_NORMALIZED_H_<br>
+<br>
+<br>
+<br>
+<br>
<br>
Added: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=192147&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=192147&view=auto</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (added)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Mon Oct  7 19:43:34 2013<br>
@@ -0,0 +1,650 @@<br>
+//===- lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp -----------------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+///<br>
+/// \file For mach-o object files, this implementation uses YAML I/O to<br>
+/// provide the convert between YAML and the normalized mach-o (NM).<br>
+///<br>
+///                  +------------+         +------+<br>
+///                  | normalized |   <->   | yaml |<br>
+///                  +------------+         +------+<br>
+<br>
+#include "MachONormalizedFile.h"<br>
+<br>
+#include "lld/Core/Error.h"<br>
+#include "lld/Core/LLVM.h"<br>
+<br>
+#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/ADT/StringSwitch.h"<br>
+#include "llvm/ADT/Twine.h"<br>
+#include "llvm/Support/Casting.h"<br>
+#include "llvm/Support/ErrorHandling.h"<br>
+#include "llvm/Support/MachO.h"<br>
+#include "llvm/Support/MemoryBuffer.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "llvm/Support/SourceMgr.h"<br>
+#include "llvm/Support/system_error.h"<br>
+#include "llvm/Support/YAMLTraits.h"<br>
+<br>
+<br>
+using llvm::StringRef;<br>
+using llvm::error_code;<br>
+using llvm::dyn_cast;<br>
+<br>
+using llvm::yaml::MappingTraits;<br>
+using llvm::yaml::SequenceTraits;<br>
+using llvm::yaml::ScalarEnumerationTraits;<br>
+using llvm::yaml::ScalarBitSetTraits;<br>
+using llvm::yaml::ScalarTraits;<br>
+using llvm::yaml::IO;<br>
+using llvm::yaml::Hex64;<br>
+using llvm::yaml::Hex32;<br>
+using llvm::yaml::Hex8;<br>
+<br>
+using llvm::MachO::HeaderFileType;<br>
+using llvm::MachO::RebaseType;<br>
+using llvm::MachO::BindType;<br>
+using llvm::MachO::NListType;<br>
+using llvm::MachO::RelocationInfoType;<br>
+using llvm::MachO::SectionType;<br>
+using llvm::MachO::LoadCommandType;<br>
+<br>
+using lld::mach_o::normalized::Section;<br>
+using lld::mach_o::normalized::Symbol;<br>
+using lld::mach_o::normalized::Relocation;<br>
+using lld::mach_o::normalized::Relocations;<br>
+using lld::mach_o::normalized::IndirectSymbols;<br>
+using lld::mach_o::normalized::ContentBytes;<br>
+using lld::mach_o::normalized::FileFlags;<br>
+using lld::mach_o::normalized::SectionAttr;<br>
+using lld::mach_o::normalized::SymbolScope;<br>
+using lld::mach_o::normalized::SymbolDesc;<br>
+using lld::mach_o::normalized::VMProtect;<br>
+using lld::mach_o::normalized::Segment;<br>
+using lld::mach_o::normalized::DependentDylib;<br>
+using lld::mach_o::normalized::RebaseLocation;<br>
+using lld::mach_o::normalized::BindLocation;<br>
+using lld::mach_o::normalized::ExportFlags;<br>
+using lld::mach_o::normalized::Export;<br>
+using lld::mach_o::normalized::NormalizedFile;<br>
+<br>
+// A vector of Sections is a sequence.<br>
+template<><br>
+struct SequenceTraits< std::vector<Section> > {<br>
+  static size_t size(IO &io, std::vector<Section> &seq) {<br>
+    return seq.size();<br>
+  }<br>
+  static Section& element(IO &io, std::vector<Section> &seq, size_t index) {<br>
+    if ( index >= seq.size() )<br>
+      seq.resize(index+1);<br>
+    return seq[index];<br>
+  }<br>
+};<br>
+<br>
+template<><br>
+struct SequenceTraits< std::vector<Symbol> > {<br>
+  static size_t size(IO &io, std::vector<Symbol> &seq) {<br>
+    return seq.size();<br>
+  }<br>
+  static Symbol& element(IO &io, std::vector<Symbol> &seq, size_t index) {<br>
+    if ( index >= seq.size() )<br>
+      seq.resize(index+1);<br>
+    return seq[index];<br>
+  }<br>
+};<br>
+<br>
+// A vector of Relocations is a sequence.<br>
+template<><br>
+struct SequenceTraits< Relocations > {<br>
+  static size_t size(IO &io, Relocations &seq) {<br>
+    return seq.size();<br>
+  }<br>
+  static Relocation& element(IO &io, Relocations &seq, size_t index) {<br>
+    if ( index >= seq.size() )<br>
+      seq.resize(index+1);<br>
+    return seq[index];<br>
+  }<br>
+};<br>
+<br>
+// The content for a section is represented as a flow sequence of hex bytes.<br>
+template<><br>
+struct SequenceTraits< ContentBytes > {<br>
+  static size_t size(IO &io, ContentBytes &seq) {<br>
+    return seq.size();<br>
+  }<br>
+  static Hex8& element(IO &io, ContentBytes &seq, size_t index) {<br>
+    if ( index >= seq.size() )<br>
+      seq.resize(index+1);<br>
+    return seq[index];<br>
+  }<br>
+  static const bool flow = true;<br>
+};<br>
+<br>
+// The indirect symbols for a section is represented as a flow sequence<br>
+// of numbers (symbol table indexes).<br>
+template<><br>
+struct SequenceTraits< IndirectSymbols > {<br>
+  static size_t size(IO &io, IndirectSymbols &seq) {<br>
+    return seq.size();<br>
+  }<br>
+  static uint32_t& element(IO &io, IndirectSymbols &seq, size_t index) {<br>
+    if ( index >= seq.size() )<br>
+      seq.resize(index+1);<br>
+    return seq[index];<br>
+  }<br>
+  static const bool flow = true;<br>
+};<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<lld::MachOLinkingContext::Arch> {<br>
+  static void enumeration(IO &io, lld::MachOLinkingContext::Arch &value) {<br>
+    io.enumCase(value, "unknown",lld::MachOLinkingContext::arch_unknown);<br>
+    io.enumCase(value, "ppc",    lld::MachOLinkingContext::arch_ppc);<br>
+    io.enumCase(value, "x86",    lld::MachOLinkingContext::arch_x86);<br>
+    io.enumCase(value, "x86_64", lld::MachOLinkingContext::arch_x86_64);<br>
+    io.enumCase(value, "armv6",  lld::MachOLinkingContext::arch_armv6);<br>
+    io.enumCase(value, "armv7",  lld::MachOLinkingContext::arch_armv7);<br>
+    io.enumCase(value, "armv7s", lld::MachOLinkingContext::arch_armv7s);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<lld::MachOLinkingContext::OS> {<br>
+  static void enumeration(IO &io, lld::MachOLinkingContext::OS &value) {<br>
+    io.enumCase(value, "unknown",<br>
+                          lld::MachOLinkingContext::OS::unknown);<br>
+    io.enumCase(value, "Mac OS X",<br>
+                          lld::MachOLinkingContext::OS::macOSX);<br>
+    io.enumCase(value, "iOS",<br>
+                          lld::MachOLinkingContext::OS::iOS);<br>
+    io.enumCase(value, "iOS Simulator",<br>
+                          lld::MachOLinkingContext::OS::iOS_simulator);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<HeaderFileType> {<br>
+  static void enumeration(IO &io, HeaderFileType &value) {<br>
+    io.enumCase(value, "object",      llvm::MachO::MH_OBJECT);<br>
+    io.enumCase(value, "dylib",       llvm::MachO::MH_DYLIB);<br>
+    io.enumCase(value, "executable",  llvm::MachO::MH_EXECUTE);<br>
+    io.enumCase(value, "bundle",      llvm::MachO::MH_BUNDLE);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct ScalarBitSetTraits<FileFlags> {<br>
+  static void bitset(IO &io, FileFlags &value) {<br>
+    io.bitSetCase(value, "MH_TWOLEVEL",<br>
+                          llvm::MachO::MH_TWOLEVEL);<br>
+    io.bitSetCase(value, "MH_SUBSECTIONS_VIA_SYMBOLS",<br>
+                          llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<SectionType> {<br>
+  static void enumeration(IO &io, SectionType &value) {<br>
+    io.enumCase(value, "S_REGULAR",<br>
+                        llvm::MachO::S_REGULAR);<br>
+    io.enumCase(value, "S_ZEROFILL",<br>
+                        llvm::MachO::S_ZEROFILL);<br>
+    io.enumCase(value, "S_CSTRING_LITERALS",<br>
+                        llvm::MachO::S_CSTRING_LITERALS);<br>
+    io.enumCase(value, "S_4BYTE_LITERALS",<br>
+                        llvm::MachO::S_4BYTE_LITERALS);<br>
+    io.enumCase(value, "S_8BYTE_LITERALS",<br>
+                        llvm::MachO::S_8BYTE_LITERALS);<br>
+    io.enumCase(value, "S_LITERAL_POINTERS",<br>
+                        llvm::MachO::S_LITERAL_POINTERS);<br>
+    io.enumCase(value, "S_NON_LAZY_SYMBOL_POINTERS",<br>
+                        llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS);<br>
+    io.enumCase(value, "S_LAZY_SYMBOL_POINTERS",<br>
+                        llvm::MachO::S_LAZY_SYMBOL_POINTERS);<br>
+    io.enumCase(value, "S_SYMBOL_STUBS",<br>
+                        llvm::MachO::S_SYMBOL_STUBS);<br>
+    io.enumCase(value, "S_MOD_INIT_FUNC_POINTERS",<br>
+                        llvm::MachO::S_MOD_INIT_FUNC_POINTERS);<br>
+    io.enumCase(value, "S_MOD_TERM_FUNC_POINTERS",<br>
+                        llvm::MachO::S_MOD_TERM_FUNC_POINTERS);<br>
+    io.enumCase(value, "S_COALESCED",<br>
+                        llvm::MachO::S_COALESCED);<br>
+    io.enumCase(value, "S_GB_ZEROFILL",<br>
+                        llvm::MachO::S_GB_ZEROFILL);<br>
+    io.enumCase(value, "S_INTERPOSING",<br>
+                        llvm::MachO::S_INTERPOSING);<br>
+    io.enumCase(value, "S_16BYTE_LITERALS",<br>
+                        llvm::MachO::S_16BYTE_LITERALS);<br>
+    io.enumCase(value, "S_DTRACE_DOF",<br>
+                        llvm::MachO::S_DTRACE_DOF);<br>
+    io.enumCase(value, "S_LAZY_DYLIB_SYMBOL_POINTERS",<br>
+                        llvm::MachO::S_LAZY_DYLIB_SYMBOL_POINTERS);<br>
+    io.enumCase(value, "S_THREAD_LOCAL_REGULAR",<br>
+                        llvm::MachO::S_THREAD_LOCAL_REGULAR);<br>
+    io.enumCase(value, "S_THREAD_LOCAL_ZEROFILL",<br>
+                        llvm::MachO::S_THREAD_LOCAL_ZEROFILL);<br>
+    io.enumCase(value, "S_THREAD_LOCAL_VARIABLES",<br>
+                        llvm::MachO::S_THREAD_LOCAL_VARIABLES);<br>
+    io.enumCase(value, "S_THREAD_LOCAL_VARIABLE_POINTERS",<br>
+                        llvm::MachO::S_THREAD_LOCAL_VARIABLE_POINTERS);<br>
+    io.enumCase(value, "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS",<br>
+                        llvm::MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct ScalarBitSetTraits<SectionAttr> {<br>
+  static void bitset(IO &io, SectionAttr &value) {<br>
+    io.bitSetCase(value, "S_ATTR_PURE_INSTRUCTIONS",<br>
+                          llvm::MachO::S_ATTR_PURE_INSTRUCTIONS);<br>
+    io.bitSetCase(value, "S_ATTR_SOME_INSTRUCTIONS",<br>
+                          llvm::MachO::S_ATTR_SOME_INSTRUCTIONS);<br>
+    io.bitSetCase(value, "S_ATTR_NO_DEAD_STRIP",<br>
+                          llvm::MachO::S_ATTR_NO_DEAD_STRIP);<br>
+    io.bitSetCase(value, "S_ATTR_EXT_RELOC",<br>
+                          llvm::MachO::S_ATTR_EXT_RELOC);<br>
+    io.bitSetCase(value, "S_ATTR_LOC_RELOC",<br>
+                          llvm::MachO::S_ATTR_LOC_RELOC);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<NListType> {<br>
+  static void enumeration(IO &io, NListType &value) {<br>
+    io.enumCase(value, "N_UNDF",  llvm::MachO::N_UNDF);<br>
+    io.enumCase(value, "N_ABS",   llvm::MachO::N_ABS);<br>
+    io.enumCase(value, "N_SECT",  llvm::MachO::N_SECT);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct ScalarBitSetTraits<SymbolScope> {<br>
+  static void bitset(IO &io, SymbolScope &value) {<br>
+    io.bitSetCase(value, "N_EXT",   llvm::MachO::N_EXT);<br>
+    io.bitSetCase(value, "N_PEXT",  llvm::MachO::N_PEXT);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct ScalarBitSetTraits<SymbolDesc> {<br>
+  static void bitset(IO &io, SymbolDesc &value) {<br>
+    io.bitSetCase(value, "N_NO_DEAD_STRIP",   llvm::MachO::N_NO_DEAD_STRIP);<br>
+    io.bitSetCase(value, "N_WEAK_REF",        llvm::MachO::N_WEAK_REF);<br>
+    io.bitSetCase(value, "N_WEAK_DEF",        llvm::MachO::N_WEAK_DEF);<br>
+    io.bitSetCase(value, "N_ARM_THUMB_DEF",   llvm::MachO::N_ARM_THUMB_DEF);<br>
+    io.bitSetCase(value, "N_SYMBOL_RESOLVER", llvm::MachO::N_SYMBOL_RESOLVER);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct MappingTraits<Section> {<br>
+  static void mapping(IO &io, Section &sect) {<br>
+    io.mapRequired("segment",         sect.segmentName);<br>
+    io.mapRequired("section",         sect.sectionName);<br>
+    io.mapRequired("type",            sect.type);<br>
+    io.mapOptional("attributes",      sect.attributes);<br>
+    io.mapOptional("alignment",       sect.alignment, 0U);<br>
+    io.mapRequired("address",         sect.address);<br>
+    io.mapOptional("content",         sect.content);<br>
+    io.mapOptional("relocations",     sect.relocations);<br>
+    io.mapOptional("indirect-syms",   sect.indirectSymbols);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct MappingTraits<Relocation> {<br>
+  static void mapping(IO &io, Relocation &reloc) {<br>
+    io.mapRequired("offset",    reloc.offset);<br>
+    io.mapOptional("scattered", reloc.scattered, false);<br>
+    io.mapRequired("type",      reloc.type);<br>
+    io.mapRequired("length",    reloc.length);<br>
+    io.mapRequired("pc-rel",    reloc.pcRel);<br>
+    if ( !reloc.scattered )<br>
+     io.mapRequired("extern",   reloc.isExtern);<br>
+    if ( reloc.scattered )<br>
+     io.mapRequired("value",    reloc.value);<br>
+    if ( !reloc.scattered )<br>
+     io.mapRequired("symbol",   reloc.symbol);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<RelocationInfoType> {<br>
+  static void enumeration(IO &io, RelocationInfoType &value) {<br>
+    NormalizedFile *file = reinterpret_cast<NormalizedFile*>(io.getContext());<br>
+    assert(file != nullptr);<br>
+    switch (file->arch) {<br>
+    case lld::MachOLinkingContext::arch_x86_64:<br>
+      io.enumCase(value, "X86_64_RELOC_UNSIGNED",<br>
+                                  llvm::MachO::X86_64_RELOC_UNSIGNED);<br>
+      io.enumCase(value, "X86_64_RELOC_SIGNED",<br>
+                                  llvm::MachO::X86_64_RELOC_SIGNED);<br>
+      io.enumCase(value, "X86_64_RELOC_BRANCH",<br>
+                                  llvm::MachO::X86_64_RELOC_BRANCH);<br>
+      io.enumCase(value, "X86_64_RELOC_GOT_LOAD",<br>
+                                  llvm::MachO::X86_64_RELOC_GOT_LOAD);<br>
+      io.enumCase(value, "X86_64_RELOC_GOT",<br>
+                                  llvm::MachO::X86_64_RELOC_GOT);<br>
+      io.enumCase(value, "X86_64_RELOC_SUBTRACTOR",<br>
+                                  llvm::MachO::X86_64_RELOC_SUBTRACTOR);<br>
+      io.enumCase(value, "X86_64_RELOC_SIGNED_1",<br>
+                                  llvm::MachO::X86_64_RELOC_SIGNED_1);<br>
+      io.enumCase(value, "X86_64_RELOC_SIGNED_2",<br>
+                                  llvm::MachO::X86_64_RELOC_SIGNED_2);<br>
+      io.enumCase(value, "X86_64_RELOC_SIGNED_4",<br>
+                                  llvm::MachO::X86_64_RELOC_SIGNED_4);<br>
+      io.enumCase(value, "X86_64_RELOC_TLV",<br>
+                                  llvm::MachO::X86_64_RELOC_TLV);<br>
+      break;<br>
+    case lld::MachOLinkingContext::arch_x86:<br>
+      io.enumCase(value, "GENERIC_RELOC_VANILLA",<br>
+                                  llvm::MachO::GENERIC_RELOC_VANILLA);<br>
+      io.enumCase(value, "GENERIC_RELOC_PAIR",<br>
+                                  llvm::MachO::GENERIC_RELOC_PAIR);<br>
+      io.enumCase(value, "GENERIC_RELOC_SECTDIFF",<br>
+                                  llvm::MachO::GENERIC_RELOC_SECTDIFF);<br>
+      io.enumCase(value, "GENERIC_RELOC_LOCAL_SECTDIFF",<br>
+                                  llvm::MachO::GENERIC_RELOC_LOCAL_SECTDIFF);<br>
+      io.enumCase(value, "GENERIC_RELOC_TLV",<br>
+                                  llvm::MachO::GENERIC_RELOC_TLV);<br>
+      break;<br>
+    case lld::MachOLinkingContext::arch_armv6:<br>
+    case lld::MachOLinkingContext::arch_armv7:<br>
+    case lld::MachOLinkingContext::arch_armv7s:<br>
+       io.enumCase(value, "ARM_RELOC_VANILLA",<br>
+                                  llvm::MachO::ARM_RELOC_VANILLA);<br>
+      io.enumCase(value, "ARM_RELOC_PAIR",<br>
+                                  llvm::MachO::ARM_RELOC_PAIR);<br>
+      io.enumCase(value, "ARM_RELOC_SECTDIFF",<br>
+                                  llvm::MachO::ARM_RELOC_SECTDIFF);<br>
+      io.enumCase(value, "ARM_RELOC_LOCAL_SECTDIFF",<br>
+                                  llvm::MachO::ARM_RELOC_LOCAL_SECTDIFF);<br>
+      io.enumCase(value, "ARM_RELOC_BR24",<br>
+                                  llvm::MachO::ARM_RELOC_BR24);<br>
+      io.enumCase(value, "ARM_THUMB_RELOC_BR22",<br>
+                                  llvm::MachO::ARM_THUMB_RELOC_BR22);<br>
+      io.enumCase(value, "ARM_RELOC_HALF",<br>
+                                  llvm::MachO::ARM_RELOC_HALF);<br>
+      io.enumCase(value, "ARM_RELOC_HALF_SECTDIFF",<br>
+                                  llvm::MachO::ARM_RELOC_HALF_SECTDIFF);<br>
+      break;<br>
+    default:<br>
+      llvm_unreachable("unknown archictecture");<br>
+    }<br>
+ }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct MappingTraits<Symbol> {<br>
+  static void mapping(IO &io, Symbol& sym) {<br>
+    io.mapRequired("name",    <a href="http://sym.name" target="_blank">sym.name</a>);<br>
+    io.mapRequired("type",    sym.type);<br>
+    io.mapOptional("scope",   sym.scope, SymbolScope(0));<br>
+    io.mapOptional("sect",    sym.sect, (uint8_t)0);<br>
+    io.mapOptional("desc",    sym.desc, SymbolDesc(0));<br>
+    io.mapRequired("value",   sym.value);<br>
+  }<br>
+};<br>
+<br>
+// Custom mapping for VMProtect (e.g. "r-x").<br>
+template <><br>
+struct ScalarTraits<VMProtect> {<br>
+  static void output(const VMProtect &value, void*, llvm::raw_ostream &out) {<br>
+    out << ( (value & llvm::MachO::VM_PROT_READ)    ? 'r' : '-');<br>
+    out << ( (value & llvm::MachO::VM_PROT_WRITE)   ? 'w' : '-');<br>
+    out << ( (value & llvm::MachO::VM_PROT_EXECUTE) ? 'x' : '-');<br>
+  }<br>
+  static StringRef input(StringRef scalar, void*, VMProtect &value) {<br>
+    value = 0;<br>
+    if (scalar.size() != 3)<br>
+      return "segment access protection must be three chars (e.g. \"r-x\")";<br>
+    switch (scalar[0]) {<br>
+    case 'r':<br>
+      value = llvm::MachO::VM_PROT_READ;<br>
+      break;<br>
+    case '-':<br>
+      break;<br>
+    default:<br>
+      return "segment access protection first char must be 'r' or '-'";<br>
+    }<br>
+    switch (scalar[1]) {<br>
+    case 'w':<br>
+      value = value | llvm::MachO::VM_PROT_WRITE;<br>
+      break;<br>
+    case '-':<br>
+      break;<br>
+    default:<br>
+      return "segment access protection second char must be 'w' or '-'";<br>
+    }<br>
+    switch (scalar[2]) {<br>
+    case 'x':<br>
+      value = value | llvm::MachO::VM_PROT_EXECUTE;<br>
+      break;<br>
+    case '-':<br>
+      break;<br>
+    default:<br>
+      return "segment access protection third char must be 'x' or '-'";<br>
+    }<br>
+    // Return the empty string on success,<br>
+    return StringRef();<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct MappingTraits<Segment> {<br>
+  static void mapping(IO &io, Segment& seg) {<br>
+    io.mapRequired("name",      <a href="http://seg.name" target="_blank">seg.name</a>);<br>
+    io.mapRequired("address",   seg.address);<br>
+    io.mapRequired("size",      seg.size);<br>
+    io.mapRequired("access",    seg.access);<br>
+  }<br>
+};<br>
+LLVM_YAML_IS_SEQUENCE_VECTOR(Segment);<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<LoadCommandType> {<br>
+  static void enumeration(IO &io, LoadCommandType &value) {<br>
+    io.enumCase(value, "LC_LOAD_DYLIB",<br>
+                        llvm::MachO::LC_LOAD_DYLIB);<br>
+    io.enumCase(value, "LC_LOAD_WEAK_DYLIB",<br>
+                        llvm::MachO::LC_LOAD_WEAK_DYLIB);<br>
+    io.enumCase(value, "LC_REEXPORT_DYLIB",<br>
+                        llvm::MachO::LC_REEXPORT_DYLIB);<br>
+    io.enumCase(value, "LC_LOAD_UPWARD_DYLIB",<br>
+                        llvm::MachO::LC_LOAD_UPWARD_DYLIB);<br>
+    io.enumCase(value, "LC_LAZY_LOAD_DYLIB",<br>
+                        llvm::MachO::LC_LAZY_LOAD_DYLIB);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct MappingTraits<DependentDylib> {<br>
+  static void mapping(IO &io, DependentDylib& dylib) {<br>
+    io.mapRequired("path",    dylib.path);<br>
+    io.mapOptional("kind",    dylib.kind,       llvm::MachO::LC_LOAD_DYLIB);<br>
+  }<br>
+};<br>
+<br>
+LLVM_YAML_IS_SEQUENCE_VECTOR(DependentDylib);<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<RebaseType> {<br>
+  static void enumeration(IO &io, RebaseType &value) {<br>
+    io.enumCase(value, "REBASE_TYPE_POINTER",<br>
+                        llvm::MachO::REBASE_TYPE_POINTER);<br>
+    io.enumCase(value, "REBASE_TYPE_TEXT_PCREL32",<br>
+                        llvm::MachO::REBASE_TYPE_TEXT_PCREL32);<br>
+    io.enumCase(value, "REBASE_TYPE_TEXT_ABSOLUTE32",<br>
+                        llvm::MachO::REBASE_TYPE_TEXT_ABSOLUTE32);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct MappingTraits<RebaseLocation> {<br>
+  static void mapping(IO &io, RebaseLocation& rebase) {<br>
+    io.mapRequired("segment-index",   rebase.segIndex);<br>
+    io.mapRequired("segment-offset",  rebase.segOffset);<br>
+    io.mapOptional("kind",            rebase.kind,<br>
+                                      llvm::MachO::REBASE_TYPE_POINTER);<br>
+  }<br>
+};<br>
+<br>
+LLVM_YAML_IS_SEQUENCE_VECTOR(RebaseLocation);<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<BindType> {<br>
+  static void enumeration(IO &io, BindType &value) {<br>
+    io.enumCase(value, "BIND_TYPE_POINTER",<br>
+                        llvm::MachO::BIND_TYPE_POINTER);<br>
+    io.enumCase(value, "BIND_TYPE_TEXT_ABSOLUTE32",<br>
+                        llvm::MachO::BIND_TYPE_TEXT_ABSOLUTE32);<br>
+    io.enumCase(value, "BIND_TYPE_TEXT_PCREL32",<br>
+                        llvm::MachO::BIND_TYPE_TEXT_PCREL32);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct MappingTraits<BindLocation> {<br>
+  static void mapping(IO &io, BindLocation &bind) {<br>
+    io.mapRequired("segment-index",   bind.segIndex);<br>
+    io.mapRequired("segment-offset",  bind.segOffset);<br>
+    io.mapOptional("kind",            bind.kind,<br>
+                                      llvm::MachO::BIND_TYPE_POINTER);<br>
+    io.mapOptional("can-be-null",     bind.canBeNull, false);<br>
+    io.mapRequired("ordinal",         bind.ordinal);<br>
+    io.mapRequired("symbol-name",     bind.symbolName);<br>
+    io.mapOptional("addend",          bind.addend, Hex64(0));<br>
+  }<br>
+};<br>
+<br>
+LLVM_YAML_IS_SEQUENCE_VECTOR(BindLocation);<br>
+<br>
+<br>
+template <><br>
+struct ScalarEnumerationTraits<ExportSymbolKind> {<br>
+  static void enumeration(IO &io, ExportSymbolKind &value) {<br>
+    io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_REGULAR",<br>
+                        llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR);<br>
+    io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCALl",<br>
+                        llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);<br>
+  }<br>
+};<br>
+<br>
+template <><br>
+struct ScalarBitSetTraits<ExportFlags> {<br>
+  static void bitset(IO &io, ExportFlags &value) {<br>
+    io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION",<br>
+                          llvm::MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);<br>
+    io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_REEXPORT",<br>
+                          llvm::MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);<br>
+    io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER",<br>
+                          llvm::MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);<br>
+  }<br>
+};<br>
+<br>
+<br>
+template <><br>
+struct MappingTraits<Export> {<br>
+  static void mapping(IO &io, Export &exp) {<br>
+    io.mapRequired("name",         <a href="http://exp.name" target="_blank">exp.name</a>);<br>
+    io.mapRequired("offset",       exp.offset);<br>
+    io.mapOptional("kind",         exp.kind,<br>
+                                llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR);<br>
+    io.mapOptional("flags",        exp.flags);<br>
+    io.mapOptional("other-offset", exp.otherOffset, Hex32(0));<br>
+    io.mapOptional("other-name",   exp.otherName, StringRef());<br>
+  }<br>
+};<br>
+<br>
+LLVM_YAML_IS_SEQUENCE_VECTOR(Export);<br>
+LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef);<br>
+<br>
+template <><br>
+struct MappingTraits<NormalizedFile> {<br>
+  static void mapping(IO &io, NormalizedFile &file) {<br>
+    io.mapRequired("arch",             file.arch);<br>
+    io.mapRequired("file-type",        file.fileType);<br>
+    io.mapOptional("flags",            file.flags);<br>
+    io.mapOptional("dependents",       file.dependentDylibs);<br>
+    io.mapOptional("install-name",     file.installName,    StringRef());<br>
+    io.mapOptional("has-UUID",         file.hasUUID,        true);<br>
+    io.mapOptional("rpaths",           file.rpaths);<br>
+    io.mapOptional("entry-point",      file.entryAddress,   Hex64(0));<br>
+    io.mapOptional("source-version",   file.sourceVersion,  Hex64(0));<br>
+    io.mapOptional("OS",               file.os);<br>
+    io.mapOptional("min-os-version",   file.minOSverson,    Hex32(0));<br>
+    io.mapOptional("sdk-version",      file.sdkVersion,     Hex32(0));<br>
+    io.mapOptional("segments",         file.segments);<br>
+    io.mapOptional("sections",         file.sections);<br>
+    io.mapOptional("local-symbols",    file.localSymbols);<br>
+    io.mapOptional("global-symbols",   file.globalSymbols);<br>
+    io.mapOptional("undefined-symbols",file.undefinedSymbols);<br>
+    io.mapOptional("rebasings",        file.rebasingInfo);<br>
+    io.mapOptional("bindings",         file.bindingInfo);<br>
+    io.mapOptional("weak-bindings",    file.weakBindingInfo);<br>
+    io.mapOptional("lazy-bindings",    file.lazyBindingInfo);<br>
+    io.mapOptional("exports",          file.exportInfo);<br>
+  }<br>
+};<br>
+<br>
+<br>
+namespace lld {<br>
+namespace mach_o {<br>
+namespace normalized {<br>
+<br>
+/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.<br>
+ErrorOr<std::unique_ptr<NormalizedFile>><br>
+readYaml(std::unique_ptr<MemoryBuffer> &mb) {<br>
+  // Make empty NormalizedFile.<br>
+  std::unique_ptr<NormalizedFile> f(new NormalizedFile());<br>
+<br>
+  // Create YAML Input parser.<br>
+  llvm::yaml::Input yin(mb->getBuffer(), f.get());<br>
+<br>
+  // Fill NormalizedFile by parsing yaml.<br>
+  yin >> *f;<br>
+<br>
+  // Return error if there were parsing problems.<br>
+  if (yin.error())<br>
+    return make_error_code(lld::yaml_reader_error::illegal_value);<br>
+<br>
+  // Hand ownership of instantiated NormalizedFile to caller.<br>
+  return std::move(f);<br>
+}<br>
+<br>
+<br>
+/// Writes a yaml encoded mach-o files from an in-memory normalized view.<br>
+error_code<br>
+writeYaml(const NormalizedFile &file, llvm::raw_ostream &out) {<br>
+  // YAML I/O is not const aware, so need to cast away ;-(<br>
+  NormalizedFile *f = const_cast<NormalizedFile*>(&file);<br>
+<br>
+  // Create yaml Output writer, using yaml options for context.<br>
+  llvm::yaml::Output yout(out, f);<br>
+<br>
+  // Stream out yaml.<br>
+  yout << *f;<br>
+<br>
+  return error_code::success();<br>
+}<br>
+<br>
+} // namespace normalized<br>
+} // namespace mach_o<br>
+} // namespace lld<br>
+<br>
<br>
Modified: lld/trunk/unittests/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/CMakeLists.txt?rev=192147&r1=192146&r2=192147&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/CMakeLists.txt?rev=192147&r1=192146&r2=192147&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/unittests/CMakeLists.txt (original)<br>
+++ lld/trunk/unittests/CMakeLists.txt Mon Oct  7 19:43:34 2013<br>
@@ -12,3 +12,4 @@ endfunction()<br>
<br>
 add_subdirectory(CoreTests)<br>
 add_subdirectory(DriverTests)<br>
+add_subdirectory(MachOTests)<br>
<br>
Added: lld/trunk/unittests/MachOTests/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/MachOTests/CMakeLists.txt?rev=192147&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/MachOTests/CMakeLists.txt?rev=192147&view=auto</a><br>


==============================================================================<br>
--- lld/trunk/unittests/MachOTests/CMakeLists.txt (added)<br>
+++ lld/trunk/unittests/MachOTests/CMakeLists.txt Mon Oct  7 19:43:34 2013<br>
@@ -0,0 +1,9 @@<br>
+<br>
+add_lld_unittest(lldMachOTests<br>
+  MachONormalizedFileYAMLTests.cpp<br>
+  )<br>
+<br>
+target_link_libraries(lldMachOTests<br>
+  lldMachO<br>
+  lldYAML<br>
+  )<br>
<br>
Added: lld/trunk/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp?rev=192147&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp?rev=192147&view=auto</a><br>


==============================================================================<br>
--- lld/trunk/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp (added)<br>
+++ lld/trunk/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp Mon Oct  7 19:43:34 2013<br>
@@ -0,0 +1,769 @@<br>
+//===- lld/unittest/MachOTests/MachONormalizedFileYAMLTests.cpp -----------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "gtest/gtest.h"<br>
+<br>
+#include "llvm/Support/MachO.h"<br>
+<br>
+#include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"<br>
+<br>
+#include <assert.h><br>
+#include <vector><br>
+<br>
+using llvm::StringRef;<br>
+using llvm::MemoryBuffer;<br>
+using llvm::ErrorOr;<br>
+using lld::mach_o::normalized::NormalizedFile;<br>
+using lld::mach_o::normalized::Symbol;<br>
+using lld::mach_o::normalized::Section;<br>
+using lld::mach_o::normalized::Relocation;<br>
+<br>
+<br>
+static std::unique_ptr<NormalizedFile> fromYAML(StringRef str) {<br>
+  std::unique_ptr<MemoryBuffer> mb(MemoryBuffer::getMemBuffer(str));<br>
+  ErrorOr<std::unique_ptr<NormalizedFile>> r<br>
+                                    = lld::mach_o::normalized::readYaml(mb);<br>
+  EXPECT_FALSE(!r);<br>
+  return std::move(*r);<br>
+}<br>
+<br>
+static void toYAML(const NormalizedFile &f, std::string &out) {<br>
+  llvm::raw_string_ostream ostr(out);<br>
+  llvm::error_code ec = lld::mach_o::normalized::writeYaml(f, ostr);<br>
+  EXPECT_TRUE(!ec);<br>
+}<br>
+<br>
+<br>
+// ppc is no longer supported, but it is here to test endianness handling.<br>
+TEST(ObjectFileYAML, empty_ppc) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      ppc\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_ppc);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+}<br>
+<br>
+TEST(ObjectFileYAML, empty_x86_64) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      x86_64\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+}<br>
+<br>
+TEST(ObjectFileYAML, empty_x86) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      x86\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+}<br>
+<br>
+TEST(ObjectFileYAML, empty_armv6) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      armv6\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv6);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+}<br>
+<br>
+TEST(ObjectFileYAML, empty_armv7) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      armv7\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+}<br>
+<br>
+TEST(ObjectFileYAML, empty_armv7s) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      armv7s\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7s);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+}<br>
+<br>
+<br>
+TEST(ObjectFileYAML, roundTrip) {<br>
+  std::string intermediate;<br>
+  {<br>
+    NormalizedFile f;<br>
+    f.arch = lld::MachOLinkingContext::arch_x86_64;<br>
+    f.fileType = llvm::MachO::MH_OBJECT;<br>
+    f.flags = llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS;<br>
+    f.os = lld::MachOLinkingContext::OS::macOSX;<br>
+    toYAML(f, intermediate);<br>
+  }<br>
+  {<br>
+    std::unique_ptr<NormalizedFile> f2 = fromYAML(intermediate);<br>
+    EXPECT_EQ(f2->arch, lld::MachOLinkingContext::arch_x86_64);<br>
+    EXPECT_EQ((int)(f2->fileType), llvm::MachO::MH_OBJECT);<br>
+    EXPECT_EQ((int)(f2->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+    EXPECT_TRUE(f2->sections.empty());<br>
+    EXPECT_TRUE(f2->localSymbols.empty());<br>
+    EXPECT_TRUE(f2->globalSymbols.empty());<br>
+    EXPECT_TRUE(f2->undefinedSymbols.empty());<br>
+  }<br>
+}<br>
+<br>
+<br>
+TEST(ObjectFileYAML, oneSymbol) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      x86_64\n"<br>
+    "file-type: object\n"<br>
+    "global-symbols:\n"<br>
+    "  - name:   _main\n"<br>
+    "    type:   N_SECT\n"<br>
+    "    scope:  [ N_EXT ]\n"<br>
+    "    sect:   1\n"<br>
+    "    desc:   [ ]\n"<br>
+    "    value:  0x100\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_TRUE(f->sections.empty());<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+  EXPECT_EQ(f->globalSymbols.size(), 1UL);<br>
+  const Symbol& sym = f->globalSymbols[0];<br>
+  EXPECT_TRUE(sym.name.equals("_main"));<br>
+  EXPECT_EQ((int)(sym.type), llvm::MachO::N_SECT);<br>
+  EXPECT_EQ((int)(sym.scope), llvm::MachO::N_EXT);<br>
+  EXPECT_EQ(sym.sect, 1);<br>
+  EXPECT_EQ((int)(sym.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym.value, 0x100ULL);<br>
+}<br>
+<br>
+<br>
+TEST(ObjectFileYAML, oneSection) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      x86_64\n"<br>
+    "file-type: object\n"<br>
+    "sections:\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __text\n"<br>
+    "    type:        S_REGULAR\n"<br>
+    "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS ]\n"<br>
+    "    alignment:   1\n"<br>
+    "    address:     0x12345678\n"<br>
+    "    content:     [ 0x90, 0x90 ]\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_TRUE(f->localSymbols.empty());<br>
+  EXPECT_TRUE(f->globalSymbols.empty());<br>
+  EXPECT_TRUE(f->undefinedSymbols.empty());<br>
+  EXPECT_EQ(f->sections.size(), 1UL);<br>
+  const Section& sect = f->sections[0];<br>
+  EXPECT_TRUE(sect.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect.sectionName.equals("__text"));<br>
+  EXPECT_EQ((uint32_t)(sect.type), (uint32_t)(llvm::MachO::S_REGULAR));<br>
+  EXPECT_EQ((uint32_t)(sect.attributes),<br>
+                            (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS));<br>
+  EXPECT_EQ(sect.alignment, 1U);<br>
+  EXPECT_EQ(sect.address, 0x12345678ULL);<br>
+  EXPECT_EQ(sect.content.size(), 2UL);<br>
+  EXPECT_EQ((int)(sect.content[0]), 0x90);<br>
+  EXPECT_EQ((int)(sect.content[1]), 0x90);<br>
+}<br>
+<br>
+<br>
+TEST(ObjectFileYAML, hello_x86_64) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      x86_64\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "sections:\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __text\n"<br>
+    "    type:        S_REGULAR\n"<br>
+    "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"<br>
+    "    alignment:   0\n"<br>
+    "    address:     0x0000\n"<br>
+    "    content:     [ 0x55, 0x48, 0x89, 0xe5, 0x48, 0x8d, 0x3d, 0x00,\n"<br>
+    "                   0x00, 0x00, 0x00, 0x30, 0xc0, 0xe8, 0x00, 0x00,\n"<br>
+    "                   0x00, 0x00, 0x31, 0xc0, 0x5d, 0xc3 ]\n"<br>
+    "    relocations:\n"<br>
+    "     - offset:     0x0e\n"<br>
+    "       type:       X86_64_RELOC_BRANCH\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     true\n"<br>
+    "       extern:     true\n"<br>
+    "       symbol:     2\n"<br>
+    "     - offset:     0x07\n"<br>
+    "       type:       X86_64_RELOC_SIGNED\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     true\n"<br>
+    "       extern:     true\n"<br>
+    "       symbol:     1\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __cstring\n"<br>
+    "    type:        S_CSTRING_LITERALS\n"<br>
+    "    attributes:  [ ]\n"<br>
+    "    alignment:   0\n"<br>
+    "    address:     0x0016\n"<br>
+    "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"<br>
+    "global-symbols:\n"<br>
+    "  - name:   _main\n"<br>
+    "    type:   N_SECT\n"<br>
+    "    scope:  [ N_EXT ]\n"<br>
+    "    sect:   1\n"<br>
+    "    value:  0x0\n"<br>
+    "local-symbols:\n"<br>
+    "  - name:   L_.str\n"<br>
+    "    type:   N_SECT\n"<br>
+    "    scope:  [ ]\n"<br>
+    "    sect:   2\n"<br>
+    "    value:  0x16\n"<br>
+    "undefined-symbols:\n"<br>
+    "  - name:   _printf\n"<br>
+    "    type:   N_UNDF\n"<br>
+    "    value:  0x0\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_EQ(f->sections.size(), 2UL);<br>
+<br>
+  const Section& sect1 = f->sections[0];<br>
+  EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect1.sectionName.equals("__text"));<br>
+  EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));<br>
+  EXPECT_EQ((uint32_t)(sect1.attributes),<br>
+                            (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS<br>
+                                     | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));<br>
+  EXPECT_EQ(sect1.alignment, 0U);<br>
+  EXPECT_EQ(sect1.address, 0x0ULL);<br>
+  EXPECT_EQ(sect1.content.size(), 22UL);<br>
+  EXPECT_EQ((int)(sect1.content[0]), 0x55);<br>
+  EXPECT_EQ((int)(sect1.content[1]), 0x48);<br>
+  EXPECT_EQ(sect1.relocations.size(), 2UL);<br>
+  const Relocation& reloc1 = sect1.relocations[0];<br>
+  EXPECT_EQ(reloc1.offset, 0x0eU);<br>
+  EXPECT_FALSE(reloc1.scattered);<br>
+  EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::X86_64_RELOC_BRANCH);<br>
+  EXPECT_EQ(reloc1.length, 2);<br>
+  EXPECT_TRUE(reloc1.pcRel);<br>
+  EXPECT_TRUE(reloc1.isExtern);<br>
+  EXPECT_EQ(reloc1.symbol, 2U);<br>
+  EXPECT_EQ((int)(reloc1.value), 0);<br>
+  const Relocation& reloc2 = sect1.relocations[1];<br>
+  EXPECT_EQ(reloc2.offset, 0x07U);<br>
+  EXPECT_FALSE(reloc2.scattered);<br>
+  EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::X86_64_RELOC_SIGNED);<br>
+  EXPECT_EQ(reloc2.length, 2);<br>
+  EXPECT_TRUE(reloc2.pcRel);<br>
+  EXPECT_TRUE(reloc2.isExtern);<br>
+  EXPECT_EQ(reloc2.symbol, 1U);<br>
+  EXPECT_EQ((int)(reloc2.value), 0);<br>
+<br>
+  const Section& sect2 = f->sections[1];<br>
+  EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect2.sectionName.equals("__cstring"));<br>
+  EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));<br>
+  EXPECT_EQ((uint32_t)(sect2.attributes), 0U);<br>
+  EXPECT_EQ(sect2.alignment, 0U);<br>
+  EXPECT_EQ(sect2.address, 0x016ULL);<br>
+  EXPECT_EQ(sect2.content.size(), 7UL);<br>
+  EXPECT_EQ((int)(sect2.content[0]), 0x68);<br>
+  EXPECT_EQ((int)(sect2.content[1]), 0x65);<br>
+  EXPECT_EQ((int)(sect2.content[2]), 0x6c);<br>
+<br>
+  EXPECT_EQ(f->globalSymbols.size(), 1UL);<br>
+  const Symbol& sym1 = f->globalSymbols[0];<br>
+  EXPECT_TRUE(sym1.name.equals("_main"));<br>
+  EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);<br>
+  EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);<br>
+  EXPECT_EQ(sym1.sect, 1);<br>
+  EXPECT_EQ((int)(sym1.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);<br>
+  EXPECT_EQ(f->localSymbols.size(), 1UL);<br>
+  const Symbol& sym2 = f->localSymbols[0];<br>
+  EXPECT_TRUE(sym2.name.equals("L_.str"));<br>
+  EXPECT_EQ((int)(sym2.type), llvm::MachO::N_SECT);<br>
+  EXPECT_EQ((int)(sym2.scope), 0);<br>
+  EXPECT_EQ(sym2.sect, 2);<br>
+  EXPECT_EQ((int)(sym2.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym2.value, 0x16ULL);<br>
+  EXPECT_EQ(f->undefinedSymbols.size(), 1UL);<br>
+  const Symbol& sym3 = f->undefinedSymbols[0];<br>
+  EXPECT_TRUE(sym3.name.equals("_printf"));<br>
+  EXPECT_EQ((int)(sym3.type), llvm::MachO::N_UNDF);<br>
+  EXPECT_EQ((int)(sym3.scope), 0);<br>
+  EXPECT_EQ(sym3.sect, 0);<br>
+  EXPECT_EQ((int)(sym3.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym3.value, 0x0ULL);<br>
+}<br>
+<br>
+<br>
+TEST(ObjectFileYAML, hello_x86) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      x86\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "sections:\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __text\n"<br>
+    "    type:        S_REGULAR\n"<br>
+    "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"<br>
+    "    alignment:   0\n"<br>
+    "    address:     0x0000\n"<br>
+    "    content:     [ 0x55, 0x89, 0xe5, 0x83, 0xec, 0x08, 0xe8, 0x00,\n"<br>
+    "                   0x00, 0x00, 0x00, 0x58, 0x8d, 0x80, 0x16, 0x00,\n"<br>
+    "                   0x00, 0x00, 0x89, 0x04, 0x24, 0xe8, 0xe6, 0xff,\n"<br>
+    "                   0xff, 0xff, 0x31, 0xc0, 0x83, 0xc4, 0x08, 0x5d,\n"<br>
+    "                   0xc3 ]\n"<br>
+    "    relocations:\n"<br>
+    "     - offset:     0x16\n"<br>
+    "       type:       GENERIC_RELOC_VANILLA\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     true\n"<br>
+    "       extern:     true\n"<br>
+    "       symbol:     1\n"<br>
+    "     - offset:     0x0e\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       GENERIC_RELOC_LOCAL_SECTDIFF\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0x21\n"<br>
+    "     - offset:     0x0\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       GENERIC_RELOC_PAIR\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0xb\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __cstring\n"<br>
+    "    type:        S_CSTRING_LITERALS\n"<br>
+    "    attributes:  [ ]\n"<br>
+    "    alignment:   0\n"<br>
+    "    address:     0x0021\n"<br>
+    "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"<br>
+    "global-symbols:\n"<br>
+    "  - name:   _main\n"<br>
+    "    type:   N_SECT\n"<br>
+    "    scope:  [ N_EXT ]\n"<br>
+    "    sect:   1\n"<br>
+    "    value:  0x0\n"<br>
+    "undefined-symbols:\n"<br>
+    "  - name:   _printf\n"<br>
+    "    type:   N_UNDF\n"<br>
+    "    value:  0x0\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_EQ(f->sections.size(), 2UL);<br>
+<br>
+  const Section& sect1 = f->sections[0];<br>
+  EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect1.sectionName.equals("__text"));<br>
+  EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));<br>
+  EXPECT_EQ((uint32_t)(sect1.attributes),<br>
+                            (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS<br>
+                                     | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));<br>
+  EXPECT_EQ(sect1.alignment, 0U);<br>
+  EXPECT_EQ(sect1.address, 0x0ULL);<br>
+  EXPECT_EQ(sect1.content.size(), 33UL);<br>
+  EXPECT_EQ((int)(sect1.content[0]), 0x55);<br>
+  EXPECT_EQ((int)(sect1.content[1]), 0x89);<br>
+  EXPECT_EQ(sect1.relocations.size(), 3UL);<br>
+  const Relocation& reloc1 = sect1.relocations[0];<br>
+  EXPECT_EQ(reloc1.offset, 0x16U);<br>
+  EXPECT_FALSE(reloc1.scattered);<br>
+  EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::GENERIC_RELOC_VANILLA);<br>
+  EXPECT_EQ(reloc1.length, 2);<br>
+  EXPECT_TRUE(reloc1.pcRel);<br>
+  EXPECT_TRUE(reloc1.isExtern);<br>
+  EXPECT_EQ(reloc1.symbol, 1U);<br>
+  EXPECT_EQ((int)(reloc1.value), 0);<br>
+  const Relocation& reloc2 = sect1.relocations[1];<br>
+  EXPECT_EQ(reloc2.offset, 0x0eU);<br>
+  EXPECT_TRUE(reloc2.scattered);<br>
+  EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::GENERIC_RELOC_LOCAL_SECTDIFF);<br>
+  EXPECT_EQ(reloc2.length, 2);<br>
+  EXPECT_FALSE(reloc2.pcRel);<br>
+  EXPECT_EQ(reloc2.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc2.value), 0x21);<br>
+  const Relocation& reloc3 = sect1.relocations[2];<br>
+  EXPECT_EQ(reloc3.offset, 0U);<br>
+  EXPECT_TRUE(reloc3.scattered);<br>
+  EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::GENERIC_RELOC_PAIR);<br>
+  EXPECT_EQ(reloc3.length, 2);<br>
+  EXPECT_FALSE(reloc3.pcRel);<br>
+  EXPECT_EQ(reloc3.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc3.value), 0xb);<br>
+<br>
+  const Section& sect2 = f->sections[1];<br>
+  EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect2.sectionName.equals("__cstring"));<br>
+  EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));<br>
+  EXPECT_EQ((uint32_t)(sect2.attributes), 0U);<br>
+  EXPECT_EQ(sect2.alignment, 0U);<br>
+  EXPECT_EQ(sect2.address, 0x021ULL);<br>
+  EXPECT_EQ(sect2.content.size(), 7UL);<br>
+  EXPECT_EQ((int)(sect2.content[0]), 0x68);<br>
+  EXPECT_EQ((int)(sect2.content[1]), 0x65);<br>
+  EXPECT_EQ((int)(sect2.content[2]), 0x6c);<br>
+<br>
+  EXPECT_EQ(f->globalSymbols.size(), 1UL);<br>
+  const Symbol& sym1 = f->globalSymbols[0];<br>
+  EXPECT_TRUE(sym1.name.equals("_main"));<br>
+  EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);<br>
+  EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);<br>
+  EXPECT_EQ(sym1.sect, 1);<br>
+  EXPECT_EQ((int)(sym1.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);<br>
+  EXPECT_EQ(f->undefinedSymbols.size(), 1UL);<br>
+  const Symbol& sym2 = f->undefinedSymbols[0];<br>
+  EXPECT_TRUE(sym2.name.equals("_printf"));<br>
+  EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);<br>
+  EXPECT_EQ((int)(sym2.scope), 0);<br>
+  EXPECT_EQ(sym2.sect, 0);<br>
+  EXPECT_EQ((int)(sym2.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);<br>
+}<br>
+<br>
+TEST(ObjectFileYAML, hello_armv6) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      armv6\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "sections:\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __text\n"<br>
+    "    type:        S_REGULAR\n"<br>
+    "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"<br>
+    "    alignment:   2\n"<br>
+    "    address:     0x0000\n"<br>
+    "    content:     [ 0x80, 0x40, 0x2d, 0xe9, 0x10, 0x00, 0x9f, 0xe5,\n"<br>
+    "                   0x0d, 0x70, 0xa0, 0xe1, 0x00, 0x00, 0x8f, 0xe0,\n"<br>
+    "                   0xfa, 0xff, 0xff, 0xeb, 0x00, 0x00, 0xa0, 0xe3,\n"<br>
+    "                   0x80, 0x80, 0xbd, 0xe8, 0x0c, 0x00, 0x00, 0x00 ]\n"<br>
+    "    relocations:\n"<br>
+    "     - offset:     0x1c\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       ARM_RELOC_SECTDIFF\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0x20\n"<br>
+    "     - offset:     0x0\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       ARM_RELOC_PAIR\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0xc\n"<br>
+    "     - offset:     0x10\n"<br>
+    "       type:       ARM_RELOC_BR24\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     true\n"<br>
+    "       extern:     true\n"<br>
+    "       symbol:     1\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __cstring\n"<br>
+    "    type:        S_CSTRING_LITERALS\n"<br>
+    "    attributes:  [ ]\n"<br>
+    "    alignment:   0\n"<br>
+    "    address:     0x0020\n"<br>
+    "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"<br>
+    "global-symbols:\n"<br>
+    "  - name:   _main\n"<br>
+    "    type:   N_SECT\n"<br>
+    "    scope:  [ N_EXT ]\n"<br>
+    "    sect:   1\n"<br>
+    "    value:  0x0\n"<br>
+    "undefined-symbols:\n"<br>
+    "  - name:   _printf\n"<br>
+    "    type:   N_UNDF\n"<br>
+    "    value:  0x0\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv6);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_EQ(f->sections.size(), 2UL);<br>
+<br>
+  const Section& sect1 = f->sections[0];<br>
+  EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect1.sectionName.equals("__text"));<br>
+  EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));<br>
+  EXPECT_EQ((uint32_t)(sect1.attributes),<br>
+                            (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS<br>
+                                     | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));<br>
+  EXPECT_EQ(sect1.alignment, 2U);<br>
+  EXPECT_EQ(sect1.address, 0x0ULL);<br>
+  EXPECT_EQ(sect1.content.size(), 32UL);<br>
+  EXPECT_EQ((int)(sect1.content[0]), 0x80);<br>
+  EXPECT_EQ((int)(sect1.content[1]), 0x40);<br>
+  EXPECT_EQ(sect1.relocations.size(), 3UL);<br>
+  const Relocation& reloc1 = sect1.relocations[0];<br>
+  EXPECT_EQ(reloc1.offset, 0x1cU);<br>
+  EXPECT_TRUE(reloc1.scattered);<br>
+  EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::ARM_RELOC_SECTDIFF);<br>
+  EXPECT_EQ(reloc1.length, 2);<br>
+  EXPECT_FALSE(reloc1.pcRel);<br>
+  EXPECT_EQ(reloc1.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc1.value), 0x20);<br>
+  const Relocation& reloc2 = sect1.relocations[1];<br>
+  EXPECT_EQ(reloc2.offset, 0x0U);<br>
+  EXPECT_TRUE(reloc2.scattered);<br>
+  EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::ARM_RELOC_PAIR);<br>
+  EXPECT_EQ(reloc2.length, 2);<br>
+  EXPECT_FALSE(reloc2.pcRel);<br>
+  EXPECT_EQ(reloc2.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc2.value), 0xc);<br>
+  const Relocation& reloc3 = sect1.relocations[2];<br>
+  EXPECT_EQ(reloc3.offset, 0x10U);<br>
+  EXPECT_FALSE(reloc3.scattered);<br>
+  EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::ARM_RELOC_BR24);<br>
+  EXPECT_EQ(reloc3.length, 2);<br>
+  EXPECT_TRUE(reloc3.pcRel);<br>
+  EXPECT_TRUE(reloc3.isExtern);<br>
+  EXPECT_EQ(reloc3.symbol, 1U);<br>
+  EXPECT_EQ((int)(reloc3.value), 0);<br>
+<br>
+  const Section& sect2 = f->sections[1];<br>
+  EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect2.sectionName.equals("__cstring"));<br>
+  EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));<br>
+  EXPECT_EQ((uint32_t)(sect2.attributes), 0U);<br>
+  EXPECT_EQ(sect2.alignment, 0U);<br>
+  EXPECT_EQ(sect2.address, 0x020ULL);<br>
+  EXPECT_EQ(sect2.content.size(), 7UL);<br>
+  EXPECT_EQ((int)(sect2.content[0]), 0x68);<br>
+  EXPECT_EQ((int)(sect2.content[1]), 0x65);<br>
+  EXPECT_EQ((int)(sect2.content[2]), 0x6c);<br>
+<br>
+  EXPECT_EQ(f->globalSymbols.size(), 1UL);<br>
+  const Symbol& sym1 = f->globalSymbols[0];<br>
+  EXPECT_TRUE(sym1.name.equals("_main"));<br>
+  EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);<br>
+  EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);<br>
+  EXPECT_EQ(sym1.sect, 1);<br>
+  EXPECT_EQ((int)(sym1.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);<br>
+  EXPECT_EQ(f->undefinedSymbols.size(), 1UL);<br>
+  const Symbol& sym2 = f->undefinedSymbols[0];<br>
+  EXPECT_TRUE(sym2.name.equals("_printf"));<br>
+  EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);<br>
+  EXPECT_EQ((int)(sym2.scope), 0);<br>
+  EXPECT_EQ(sym2.sect, 0);<br>
+  EXPECT_EQ((int)(sym2.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);<br>
+}<br>
+<br>
+<br>
+<br>
+TEST(ObjectFileYAML, hello_armv7) {<br>
+  std::unique_ptr<NormalizedFile> f = fromYAML(<br>
+    "---\n"<br>
+    "arch:      armv7\n"<br>
+    "file-type: object\n"<br>
+    "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"<br>
+    "sections:\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __text\n"<br>
+    "    type:        S_REGULAR\n"<br>
+    "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"<br>
+    "    alignment:   1\n"<br>
+    "    address:     0x0000\n"<br>
+    "    content:     [ 0x80, 0xb5, 0x40, 0xf2, 0x06, 0x00, 0x6f, 0x46,\n"<br>
+    "                   0xc0, 0xf2, 0x00, 0x00, 0x78, 0x44, 0xff, 0xf7,\n"<br>
+    "                   0xf8, 0xef, 0x00, 0x20, 0x80, 0xbd ]\n"<br>
+    "    relocations:\n"<br>
+    "     - offset:     0x0e\n"<br>
+    "       type:       ARM_THUMB_RELOC_BR22\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     true\n"<br>
+    "       extern:     true\n"<br>
+    "       symbol:     1\n"<br>
+    "     - offset:     0x08\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       ARM_RELOC_HALF_SECTDIFF\n"<br>
+    "       length:     3\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0x16\n"<br>
+    "     - offset:     0x06\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       ARM_RELOC_PAIR\n"<br>
+    "       length:     3\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0xc\n"<br>
+    "     - offset:     0x02\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       ARM_RELOC_HALF_SECTDIFF\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0x16\n"<br>
+    "     - offset:     0x0\n"<br>
+    "       scattered:  true\n"<br>
+    "       type:       ARM_RELOC_PAIR\n"<br>
+    "       length:     2\n"<br>
+    "       pc-rel:     false\n"<br>
+    "       value:      0xc\n"<br>
+    "  - segment:     __TEXT\n"<br>
+    "    section:     __cstring\n"<br>
+    "    type:        S_CSTRING_LITERALS\n"<br>
+    "    attributes:  [ ]\n"<br>
+    "    alignment:   0\n"<br>
+    "    address:     0x0016\n"<br>
+    "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"<br>
+    "global-symbols:\n"<br>
+    "  - name:   _main\n"<br>
+    "    type:   N_SECT\n"<br>
+    "    scope:  [ N_EXT ]\n"<br>
+    "    sect:   1\n"<br>
+    "    desc:   [ N_ARM_THUMB_DEF ]\n"<br>
+    "    value:  0x0\n"<br>
+    "undefined-symbols:\n"<br>
+    "  - name:   _printf\n"<br>
+    "    type:   N_UNDF\n"<br>
+    "    value:  0x0\n"<br>
+    "...\n");<br>
+  EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);<br>
+  EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);<br>
+  EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);<br>
+  EXPECT_EQ(f->sections.size(), 2UL);<br>
+<br>
+  const Section& sect1 = f->sections[0];<br>
+  EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect1.sectionName.equals("__text"));<br>
+  EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));<br>
+  EXPECT_EQ((uint32_t)(sect1.attributes),<br>
+                            (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS<br>
+                                     | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));<br>
+  EXPECT_EQ(sect1.alignment, 1U);<br>
+  EXPECT_EQ(sect1.address, 0x0ULL);<br>
+  EXPECT_EQ(sect1.content.size(), 22UL);<br>
+  EXPECT_EQ((int)(sect1.content[0]), 0x80);<br>
+  EXPECT_EQ((int)(sect1.content[1]), 0xb5);<br>
+  EXPECT_EQ(sect1.relocations.size(), 5UL);<br>
+  const Relocation& reloc1 = sect1.relocations[0];<br>
+  EXPECT_EQ(reloc1.offset, 0x0eU);<br>
+  EXPECT_FALSE(reloc1.scattered);<br>
+  EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::ARM_THUMB_RELOC_BR22);<br>
+  EXPECT_EQ(reloc1.length, 2);<br>
+  EXPECT_TRUE(reloc1.pcRel);<br>
+  EXPECT_TRUE(reloc1.isExtern);<br>
+  EXPECT_EQ(reloc1.symbol, 1U);<br>
+  EXPECT_EQ((int)(reloc1.value), 0);<br>
+  const Relocation& reloc2 = sect1.relocations[1];<br>
+  EXPECT_EQ(reloc2.offset, 0x8U);<br>
+  EXPECT_TRUE(reloc2.scattered);<br>
+  EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::ARM_RELOC_HALF_SECTDIFF);<br>
+  EXPECT_EQ(reloc2.length, 3);<br>
+  EXPECT_FALSE(reloc2.pcRel);<br>
+  EXPECT_EQ(reloc2.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc2.value), 0x16);<br>
+  const Relocation& reloc3 = sect1.relocations[2];<br>
+  EXPECT_EQ(reloc3.offset, 0x6U);<br>
+  EXPECT_TRUE(reloc3.scattered);<br>
+  EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::ARM_RELOC_PAIR);<br>
+  EXPECT_EQ(reloc3.length, 3);<br>
+  EXPECT_FALSE(reloc3.pcRel);<br>
+  EXPECT_EQ(reloc3.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc3.value), 0xc);<br>
+   const Relocation& reloc4 = sect1.relocations[3];<br>
+  EXPECT_EQ(reloc4.offset, 0x2U);<br>
+  EXPECT_TRUE(reloc4.scattered);<br>
+  EXPECT_EQ((int)reloc4.type, (int)llvm::MachO::ARM_RELOC_HALF_SECTDIFF);<br>
+  EXPECT_EQ(reloc4.length, 2);<br>
+  EXPECT_FALSE(reloc4.pcRel);<br>
+  EXPECT_EQ(reloc4.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc4.value), 0x16);<br>
+  const Relocation& reloc5 = sect1.relocations[4];<br>
+  EXPECT_EQ(reloc5.offset, 0x0U);<br>
+  EXPECT_TRUE(reloc5.scattered);<br>
+  EXPECT_EQ((int)reloc5.type, (int)llvm::MachO::ARM_RELOC_PAIR);<br>
+  EXPECT_EQ(reloc5.length, 2);<br>
+  EXPECT_FALSE(reloc5.pcRel);<br>
+  EXPECT_EQ(reloc5.symbol, 0U);<br>
+  EXPECT_EQ((int)(reloc5.value), 0xc);<br>
+<br>
+  const Section& sect2 = f->sections[1];<br>
+  EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));<br>
+  EXPECT_TRUE(sect2.sectionName.equals("__cstring"));<br>
+  EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));<br>
+  EXPECT_EQ((uint32_t)(sect2.attributes), 0U);<br>
+  EXPECT_EQ(sect2.alignment, 0U);<br>
+  EXPECT_EQ(sect2.address, 0x016ULL);<br>
+  EXPECT_EQ(sect2.content.size(), 7UL);<br>
+  EXPECT_EQ((int)(sect2.content[0]), 0x68);<br>
+  EXPECT_EQ((int)(sect2.content[1]), 0x65);<br>
+  EXPECT_EQ((int)(sect2.content[2]), 0x6c);<br>
+<br>
+  EXPECT_EQ(f->globalSymbols.size(), 1UL);<br>
+  const Symbol& sym1 = f->globalSymbols[0];<br>
+  EXPECT_TRUE(sym1.name.equals("_main"));<br>
+  EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);<br>
+  EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);<br>
+  EXPECT_EQ(sym1.sect, 1);<br>
+  EXPECT_EQ((int)(sym1.desc), (int)(llvm::MachO::N_ARM_THUMB_DEF));<br>
+  EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);<br>
+  EXPECT_EQ(f->undefinedSymbols.size(), 1UL);<br>
+  const Symbol& sym2 = f->undefinedSymbols[0];<br>
+  EXPECT_TRUE(sym2.name.equals("_printf"));<br>
+  EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);<br>
+  EXPECT_EQ((int)(sym2.scope), 0);<br>
+  EXPECT_EQ(sym2.sect, 0);<br>
+  EXPECT_EQ((int)(sym2.desc), 0);<br>
+  EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>