<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 25, 2016 at 2:56 PM, Chris Bieneman <span dir="ltr"><<a href="mailto:beanz@apple.com" target="_blank">beanz@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Sean,<div><br></div><div>I just want to fill in a bit more context on this change. The __LLVM,__bundle section is created by ld64. The sources for that are on <a href="http://opensource.apple.com" target="_blank">opensource.apple.com</a> here:</div><div><br></div><div><a href="https://opensource.apple.com/source/ld64/ld64-253.9/src/ld/passes/bitcode_bundle.cpp" target="_blank">https://opensource.apple.com/source/ld64/ld64-253.9/src/ld/passes/bitcode_bundle.cpp</a></div><div><br></div><div>It will eventually be supported in lld as well, but we’d prefer to not hold back open sourcing the ability to read object files created by ld64 until lld is fully functioning for MachO.</div><div><br></div><div>Clang’s -fembed-bitcode option embeds bit code data directly into the __LLVM,__bitcode section, which is not wrapped in a xar archive, and never will be. We use xar for fully linked binaries because it needs to contain the IR from multiple object files.</div><div><br></div><div>Kevin’s change adds functionality that is present today in otool to objdump so that it can display the contents of the xar archive.</div><div><br></div><div>Does this address your concerns about the timeline for introducing this patch?</div></div></blockquote><div><br></div><div>Yes. But it doesn't address the lack of tests ;) Can we add this code in more incrementally than just a patch dump with a single sanity check test case? There's also numerous violations of the coding standard for variable names.</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class="HOEnZb"><font color="#888888"><div><br></div><div>-Chris</div></font></span><div><div class="h5"><div><br></div><div><br><div><blockquote type="cite"><div>On May 25, 2016, at 1:16 PM, Sean Silva via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:</div><br><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 25, 2016 at 10:55 AM, Kevin Enderby <span dir="ltr"><<a href="mailto:enderby@apple.com" target="_blank">enderby@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><blockquote type="cite"><div>On May 24, 2016, at 7:27 PM, Sean Silva <<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>> wrote:</div><br><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 23, 2016 at 2:34 PM, Kevin Enderby via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: enderby<br>
Date: Mon May 23 16:34:12 2016<br>
New Revision: 270491<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=270491&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=270491&view=rev</a><br>
Log:<br>
Add the printing the Mach-O (__LLVM,__bundle) xar archive file section "verbosely"<br>
to llvm-objdump. This section is created with -fembed-bitcode option.<br></blockquote><div><br></div><div>I don't see the code to do that for -fembed-bitcode.</div></div></div></div></div></blockquote><div><br></div></span>This exists today with the clang compilers Apple ships.</div></div></blockquote><div><br></div><div>I think it makes sense to add when that feature is upstream.</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> Can we hold off until we have a real test case to dump?</div></div></div></div></div></blockquote><div><br></div></span>The test case below was created with the Apple shipping compiler with:</div><div><br></div><div>cc -o LLVM-bundle.macho-x86_64 hello.c -fembed-bitcode</div><div><br></div><div>So the test case is quite real.  Apple would very much like to have this functionally in llvm-obdump so it can be used as a replacement to the old otool-classic(1) that has this functionality.</div><div><div><div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
This requires the use of libxar and the Cmake and lit support were crafted by<br>
Chris Bieneman!<br>
<br>
<a>rdar://26202242</a><br>
<br>
Added:<br>
    llvm/trunk/test/tools/llvm-objdump/Inputs/LLVM-bundle.macho-x86_64   (with props)<br>
    llvm/trunk/test/tools/llvm-objdump/macho-LLVM-bundle.test<br>
Modified:<br>
    llvm/trunk/cmake/config-ix.cmake<br>
    llvm/trunk/include/llvm/Config/config.h.cmake<br>
    llvm/trunk/lib/Object/CMakeLists.txt<br>
    llvm/trunk/test/lit.cfg<br>
    llvm/trunk/test/<a href="http://lit.site.cfg.in/" rel="noreferrer" target="_blank">lit.site.cfg.in</a><br>
    llvm/trunk/tools/llvm-objdump/MachODump.cpp<br>
<br>
Modified: llvm/trunk/cmake/config-ix.cmake<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=270491&r1=270490&r2=270491&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=270491&r1=270490&r2=270491&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/cmake/config-ix.cmake (original)<br>
+++ llvm/trunk/cmake/config-ix.cmake Mon May 23 16:34:12 2016<br>
@@ -141,6 +141,11 @@ if( NOT PURE_WINDOWS AND NOT LLVM_USE_SA<br>
   endif()<br>
 endif()<br>
<br>
+check_library_exists(xar xar_open "" HAVE_LIBXAR)<br>
+if(HAVE_LIBXAR)<br>
+  set(XAR_LIB xar)<br>
+endif()<br>
+<br>
 # function checks<br>
 check_symbol_exists(arc4random "stdlib.h" HAVE_DECL_ARC4RANDOM)<br>
 check_symbol_exists(backtrace "execinfo.h" HAVE_BACKTRACE)<br>
<br>
Modified: llvm/trunk/include/llvm/Config/config.h.cmake<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=270491&r1=270490&r2=270491&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=270491&r1=270490&r2=270491&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Config/config.h.cmake (original)<br>
+++ llvm/trunk/include/llvm/Config/config.h.cmake Mon May 23 16:34:12 2016<br>
@@ -322,6 +322,9 @@<br>
 /* Define if the setupterm() function is supported this platform. */<br>
 #cmakedefine HAVE_TERMINFO ${HAVE_TERMINFO}<br>
<br>
+/* Define if the xar_open() function is supported this platform. */<br>
+#cmakedefine HAVE_LIBXAR ${HAVE_LIBXAR}<br>
+<br>
 /* Define to 1 if you have the <termios.h> header file. */<br>
 #cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}<br>
<br>
<br>
Modified: llvm/trunk/lib/Object/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/CMakeLists.txt?rev=270491&r1=270490&r2=270491&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/CMakeLists.txt?rev=270491&r1=270490&r2=270491&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Object/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/Object/CMakeLists.txt Mon May 23 16:34:12 2016<br>
@@ -21,4 +21,6 @@ add_llvm_library(LLVMObject<br>
<br>
   DEPENDS<br>
   intrinsics_gen<br>
+<br>
+  LINK_LIBS ${XAR_LIB}<br>
   )<br>
<br>
Modified: llvm/trunk/test/lit.cfg<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=270491&r1=270490&r2=270491&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=270491&r1=270490&r2=270491&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/lit.cfg (original)<br>
+++ llvm/trunk/test/lit.cfg Mon May 23 16:34:12 2016<br>
@@ -497,3 +497,6 @@ except OSError:<br>
 if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):<br>
     config.available_features.add('global-isel')<br>
 llvm_config_cmd.wait()<br>
+<br>
+if config.have_libxar:<br>
+    config.available_features.add('xar')<br>
<br>
Modified: llvm/trunk/test/<a href="http://lit.site.cfg.in/" rel="noreferrer" target="_blank">lit.site.cfg.in</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.site.cfg.in?rev=270491&r1=270490&r2=270491&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.site.cfg.in?rev=270491&r1=270490&r2=270491&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/<a href="http://lit.site.cfg.in/" rel="noreferrer" target="_blank">lit.site.cfg.in</a> (original)<br>
+++ llvm/trunk/test/<a href="http://lit.site.cfg.in/" rel="noreferrer" target="_blank">lit.site.cfg.in</a> Mon May 23 16:34:12 2016<br>
@@ -34,6 +34,7 @@ config.host_ldflags = "@HOST_LDFLAGS@"<br>
 config.llvm_use_intel_jitevents = "@LLVM_USE_INTEL_JITEVENTS@"<br>
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"<br>
 config.have_zlib = "@HAVE_LIBZ@"<br>
+config.have_libxar = "@HAVE_LIBXAR@"<br>
 config.have_dia_sdk = @HAVE_DIA_SDK@<br>
 config.enable_ffi = "@LLVM_ENABLE_FFI@"<br>
 config.test_examples = "@ENABLE_EXAMPLES@"<br>
<br>
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/LLVM-bundle.macho-x86_64<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/LLVM-bundle.macho-x86_64?rev=270491&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/LLVM-bundle.macho-x86_64?rev=270491&view=auto</a><br>
==============================================================================<br>
Binary file - no diff available.<br>
<br>
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/LLVM-bundle.macho-x86_64<br>
------------------------------------------------------------------------------<br>
    svn:executable = *<br>
<br>
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/LLVM-bundle.macho-x86_64<br>
------------------------------------------------------------------------------<br>
    svn:mime-type = application/octet-stream<br>
<br>
Added: llvm/trunk/test/tools/llvm-objdump/macho-LLVM-bundle.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/macho-LLVM-bundle.test?rev=270491&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/macho-LLVM-bundle.test?rev=270491&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objdump/macho-LLVM-bundle.test (added)<br>
+++ llvm/trunk/test/tools/llvm-objdump/macho-LLVM-bundle.test Mon May 23 16:34:12 2016<br>
@@ -0,0 +1,60 @@<br>
+# REQUIRES: xar<br>
+# RUN: llvm-objdump -macho -archive-headers -section __LLVM,__bundle %p/Inputs/LLVM-bundle.macho-x86_64 | FileCheck %s<br>
+<br>
+# CHECK: For (__LLVM,__bundle) section: xar header<br>
+# CHECK:                   magic XAR_HEADER_MAGIC<br>
+# CHECK:                    size 28<br>
+# CHECK:                 version 1<br>
+# CHECK:   toc_length_compressed 542<br>
+# CHECK: toc_length_uncompressed 1250<br>
+# CHECK:               cksum_alg XAR_CKSUM_SHA1<br>
+# CHECK: For (__LLVM,__bundle) section: xar archive files:<br>
+# CHECK:    1664 1<br>
+# CHECK: For (__LLVM,__bundle) section: xar table of contents:<br>
+# CHECK: <?xml version="1.0" encoding="UTF-8"?><br>
+# CHECK: <xar><br>
+# CHECK:  <subdoc subdoc_name="Ld"><br>
+# CHECK:   <version>1.0</version><br>
+# CHECK:   <architecture>x86_64</architecture><br>
+# CHECK:   <platform>MacOSX</platform><br>
+# CHECK:   <sdkversion>10.11.0</sdkversion><br>
+# CHECK:   <dylibs><br>
+# CHECK:    <lib>libSystem.dylib</lib><br>
+# CHECK:   </dylibs><br>
+# CHECK:   <link-options><br>
+# CHECK:    <option>-execute</option><br>
+# CHECK:    <option>-macosx_version_min</option><br>
+# CHECK:    <option>10.11.0</option><br>
+# CHECK:    <option>-e</option><br>
+# CHECK:    <option>_main</option><br>
+# CHECK:    <option>-executable_path</option><br>
+# CHECK:    <option>hello</option><br>
+# CHECK:   </link-options><br>
+# CHECK:  </subdoc><br>
+# CHECK:  <toc><br>
+# CHECK:   <checksum style="sha1"><br>
+# CHECK:    <size>20</size><br>
+# CHECK:    <offset>0</offset><br>
+# CHECK:   </checksum><br>
+# CHECK:   <creation-time>2016-05-23T20:49:10</creation-time><br>
+# CHECK:   <file id="1"><br>
+# CHECK:    <name>1</name><br>
+# CHECK:    <type>file</type><br>
+# CHECK:    <data><br>
+# CHECK:     <archived-checksum style="sha1">a319940ff5f5248ca8b44cf7b4b65e7dd49a47ab</archived-checksum><br>
+# CHECK:     <extracted-checksum style="sha1">a319940ff5f5248ca8b44cf7b4b65e7dd49a47ab</extracted-checksum><br>
+# CHECK:     <size>1664</size><br>
+# CHECK:     <offset>20</offset><br>
+# CHECK:     <encoding style="application/octet-stream"/><br>
+# CHECK:     <length>1664</length><br>
+# CHECK:    </data><br>
+# CHECK:    <file-type>Bitcode</file-type><br>
+# CHECK:    <clang><br>
+# CHECK:     <cmd>-triple</cmd><br>
+# CHECK:     <cmd>x86_64-apple-macosx10.11.0</cmd><br>
+# CHECK:     <cmd>-emit-obj</cmd><br>
+# CHECK:     <cmd>-disable-llvm-optzns</cmd><br>
+# CHECK:    </clang><br>
+# CHECK:   </file><br>
+# CHECK:  </toc><br>
+# CHECK: </xar><br>
<br>
Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=270491&r1=270490&r2=270491&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=270491&r1=270490&r2=270491&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)<br>
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Mon May 23 16:34:12 2016<br>
@@ -42,6 +42,7 @@<br>
 #include "llvm/Support/MemoryBuffer.h"<br>
 #include "llvm/Support/TargetRegistry.h"<br>
 #include "llvm/Support/TargetSelect.h"<br>
+#include "llvm/Support/ToolOutputFile.h"<br>
 #include "llvm/Support/raw_ostream.h"<br>
 #include <algorithm><br>
 #include <cstring><br>
@@ -51,6 +52,12 @@<br>
 #include <cxxabi.h><br>
 #endif<br>
<br>
+#ifdef HAVE_LIBXAR<br>
+extern "C" {<br>
+#include <xar/xar.h><br>
+}<br>
+#endif<br>
+<br>
 using namespace llvm;<br>
 using namespace object;<br>
<br>
@@ -1041,6 +1048,12 @@ static void DisassembleMachO(StringRef F<br>
                              StringRef DisSegName, StringRef DisSectName);<br>
 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,<br>
                                 uint32_t size, uint32_t addr);<br>
+#ifdef HAVE_LIBXAR<br>
+static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,<br>
+                                uint32_t size, bool verbose,<br>
+                                bool PrintXarHeader, bool PrintXarFileHeaders,<br>
+                                std::string XarMemberName);<br>
+#endif // defined(HAVE_LIBXAR)<br>
<br>
 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,<br>
                                 bool verbose) {<br>
@@ -1102,6 +1115,13 @@ static void DumpSectionContents(StringRe<br>
             DumpProtocolSection(O, sect, sect_size, sect_addr);<br>
             continue;<br>
           }<br>
+#ifdef HAVE_LIBXAR<br>
+          if (SegName == "__LLVM" && SectName == "__bundle") {<br>
+            DumpBitcodeSection(O, sect, sect_size, verbose, !NoSymbolicOperands,<br>
+                               ArchiveHeaders, "");<br>
+            continue;<br>
+          }<br>
+#endif // defined(HAVE_LIBXAR)<br>
           switch (section_type) {<br>
           case MachO::S_REGULAR:<br>
             DumpRawSectionContents(O, sect, sect_size, sect_addr);<br>
@@ -5645,6 +5665,369 @@ static void DumpProtocolSection(MachOObj<br>
   }<br>
 }<br>
<br>
+#ifdef HAVE_LIBXAR<br>
+inline void swapStruct(struct xar_header &xar) {<br>
+  sys::swapByteOrder(xar.magic);<br>
+  sys::swapByteOrder(xar.size);<br>
+  sys::swapByteOrder(xar.version);<br>
+  sys::swapByteOrder(xar.toc_length_compressed);<br>
+  sys::swapByteOrder(xar.toc_length_uncompressed);<br>
+  sys::swapByteOrder(xar.cksum_alg);<br>
+}<br>
+<br>
+static void PrintModeVerbose(uint32_t mode) {<br>
+  switch(mode & S_IFMT){<br>
+  case S_IFDIR:<br>
+    outs() << "d";<br>
+    break;<br>
+  case S_IFCHR:<br>
+    outs() << "c";<br>
+    break;<br>
+  case S_IFBLK:<br>
+    outs() << "b";<br>
+    break;<br>
+  case S_IFREG:<br>
+    outs() << "-";<br>
+    break;<br>
+  case S_IFLNK:<br>
+    outs() << "l";<br>
+    break;<br>
+  case S_IFSOCK:<br>
+    outs() << "s";<br>
+    break;<br>
+  default:<br>
+    outs() << "?";<br>
+    break;<br>
+  }<br>
+<br>
+  /* owner permissions */<br>
+  if(mode & S_IREAD)<br>
+    outs() << "r";<br>
+  else<br>
+    outs() << "-";<br>
+  if(mode & S_IWRITE)<br>
+    outs() << "w";<br>
+  else<br>
+    outs() << "-";<br>
+  if(mode & S_ISUID)<br>
+    outs() << "s";<br>
+  else if(mode & S_IEXEC)<br>
+    outs() << "x";<br>
+  else<br>
+    outs() << "-";<br>
+<br>
+  /* group permissions */<br>
+  if(mode & (S_IREAD >> 3))<br>
+    outs() << "r";<br>
+  else<br>
+    outs() << "-";<br>
+  if(mode & (S_IWRITE >> 3))<br>
+    outs() << "w";<br>
+  else<br>
+    outs() << "-";<br>
+  if(mode & S_ISGID)<br>
+    outs() << "s";<br>
+  else if(mode & (S_IEXEC >> 3))<br>
+    outs() << "x";<br>
+  else<br>
+    outs() << "-";<br>
+<br>
+  /* other permissions */<br>
+  if(mode & (S_IREAD >> 6))<br>
+    outs() << "r";<br>
+  else<br>
+    outs() << "-";<br>
+  if(mode & (S_IWRITE >> 6))<br>
+    outs() << "w";<br>
+  else<br>
+    outs() << "-";<br>
+  if(mode & S_ISVTX)<br>
+    outs() << "t";<br>
+  else if(mode & (S_IEXEC >> 6))<br>
+    outs() << "x";<br>
+  else<br>
+    outs() << "-";<br>
+}<br>
+<br>
+static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {<br>
+  xar_iter_t xi;<br>
+  xar_file_t xf;<br>
+  xar_iter_t xp;<br>
+  const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;<br>
+  char *endp;<br>
+  uint32_t mode_value;<br>
+<br>
+  xi = xar_iter_new();<br>
+  if (!xi) {<br>
+    errs() << "Can't obtain an xar iterator for xar archive "<br>
+           << XarFilename << "\n";<br>
+    return;<br>
+  }<br>
+<br>
+  // Go through the xar's files.<br>
+  for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {<br>
+    xp = xar_iter_new();<br>
+    if(!xp){<br>
+      errs() << "Can't obtain an xar iterator for xar archive "<br>
+             << XarFilename << "\n";<br>
+      return;<br>
+    }<br>
+    type = nullptr;<br>
+    mode = nullptr;<br>
+    user = nullptr;<br>
+    group = nullptr;<br>
+    size = nullptr;<br>
+    mtime = nullptr;<br>
+    name = nullptr;<br>
+    for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){<br>
+      const char *val = nullptr;<br>
+      xar_prop_get(xf, key, &val);<br>
+#if 0 // Useful for debugging.<br>
+      outs() << "key: " << key << " value: " << val << "\n";<br>
+#endif<br>
+      if(strcmp(key, "type") == 0)<br>
+        type = val;<br>
+      if(strcmp(key, "mode") == 0)<br>
+        mode = val;<br>
+      if(strcmp(key, "user") == 0)<br>
+        user = val;<br>
+      if(strcmp(key, "group") == 0)<br>
+        group = val;<br>
+      if(strcmp(key, "data/size") == 0)<br>
+        size = val;<br>
+      if(strcmp(key, "mtime") == 0)<br>
+        mtime = val;<br>
+      if(strcmp(key, "name") == 0)<br>
+        name = val;<br>
+    }<br>
+    if(mode != nullptr){<br>
+      mode_value = strtoul(mode, &endp, 8);<br>
+      if(*endp != '\0')<br>
+        outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";<br>
+      if(strcmp(type, "file") == 0)<br>
+        mode_value |= S_IFREG;<br>
+      PrintModeVerbose(mode_value);<br>
+      outs() << " ";<br>
+    }<br>
+    if(user != nullptr)<br>
+      outs() << format("%10s/", user);<br>
+    if(group != nullptr)<br>
+      outs() << format("%-10s ", group);<br>
+    if(size != nullptr)<br>
+      outs() << format("%7s ", size);<br>
+    if(mtime != nullptr){<br>
+      for(m = mtime; *m != 'T' && *m != '\0'; m++)<br>
+        outs() << *m;<br>
+      if(*m == 'T')<br>
+        m++;<br>
+      outs() << " ";<br>
+      for( ; *m != 'Z' && *m != '\0'; m++)<br>
+        outs() << *m;<br>
+      outs() << " ";<br>
+    }<br>
+    if(name != nullptr)<br>
+      outs() << name;<br>
+    outs() << "\n";<br>
+  }<br>
+}<br>
+<br>
+static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,<br>
+                                uint32_t size, bool verbose,<br>
+                                bool PrintXarHeader, bool PrintXarFileHeaders,<br>
+                                std::string XarMemberName) {<br>
+  if(size < sizeof(struct xar_header)) {<br>
+    outs() << "size of (__LLVM,__bundle) section too small (smaller than size "<br>
+              "of struct xar_header)\n";<br>
+    return;<br>
+  }<br>
+  struct xar_header XarHeader;<br>
+  memcpy(&XarHeader, sect, sizeof(struct xar_header));<br>
+  if (sys::IsLittleEndianHost)<br>
+    swapStruct(XarHeader);<br>
+  if (PrintXarHeader) {<br>
+    if (!XarMemberName.empty())<br>
+      outs() << "In xar member " << XarMemberName << ": ";<br>
+    else<br>
+      outs() << "For (__LLVM,__bundle) section: ";<br>
+    outs() << "xar header\n";<br>
+    if (XarHeader.magic == XAR_HEADER_MAGIC)<br>
+      outs() << "                  magic XAR_HEADER_MAGIC\n";<br>
+    else<br>
+      outs() << "                  magic "<br>
+             << format_hex(XarHeader.magic, 10, true)<br>
+             << " (not XAR_HEADER_MAGIC)\n";<br>
+    outs() << "                   size " << XarHeader.size << "\n";<br>
+    outs() << "                version " << XarHeader.version << "\n";<br>
+    outs() << "  toc_length_compressed " << XarHeader.toc_length_compressed<br>
+           << "\n";<br>
+    outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed<br>
+           << "\n";<br>
+    outs() << "              cksum_alg ";<br>
+    switch (XarHeader.cksum_alg) {<br>
+      case XAR_CKSUM_NONE:<br>
+        outs() << "XAR_CKSUM_NONE\n";<br>
+        break;<br>
+      case XAR_CKSUM_SHA1:<br>
+        outs() << "XAR_CKSUM_SHA1\n";<br>
+        break;<br>
+      case XAR_CKSUM_MD5:<br>
+        outs() << "XAR_CKSUM_MD5\n";<br>
+        break;<br>
+      case XAR_CKSUM_SHA256:<br>
+        outs() << "XAR_CKSUM_SHA256\n";<br>
+        break;<br>
+      case XAR_CKSUM_SHA512:<br>
+        outs() << "XAR_CKSUM_SHA512\n";<br>
+        break;<br>
+      default:<br>
+        outs() << XarHeader.cksum_alg << "\n";<br>
+    }<br>
+  }<br>
+<br>
+  SmallString<128> XarFilename;<br>
+  int FD;<br>
+  std::error_code XarEC =<br>
+      sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);<br>
+  if (XarEC) {<br>
+    errs() << XarEC.message() << "\n";<br>
+    return;<br>
+  }<br>
+  tool_output_file XarFile(XarFilename, FD);<br>
+  raw_fd_ostream &XarOut = XarFile.os();<br>
+  StringRef XarContents(sect, size);<br>
+  XarOut << XarContents;<br>
+  XarOut.close();<br>
+  if (XarOut.has_error())<br>
+    return;<br>
+<br>
+  xar_t xar = xar_open(XarFilename.c_str(), READ);<br>
+  if (!xar) {<br>
+    errs() << "Can't create temporary xar archive " << XarFilename << "\n";<br>
+    return;<br>
+  }<br>
+<br>
+  SmallString<128> TocFilename;<br>
+  std::error_code TocEC =<br>
+      sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);<br>
+  if (TocEC) {<br>
+    errs() << TocEC.message() << "\n";<br>
+    return;<br>
+  }<br>
+  xar_serialize(xar, TocFilename.c_str());<br>
+<br>
+  if (PrintXarFileHeaders) {<br>
+    if (!XarMemberName.empty())<br>
+      outs() << "In xar member " << XarMemberName << ": ";<br>
+    else<br>
+      outs() << "For (__LLVM,__bundle) section: ";<br>
+    outs() << "xar archive files:\n";<br>
+    PrintXarFilesSummary(XarFilename.c_str(), xar);<br>
+  }<br>
+<br>
+  ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =<br>
+    MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());<br>
+  if (std::error_code EC = FileOrErr.getError()) {<br>
+    errs() << EC.message() << "\n";<br>
+    return;<br>
+  }<br>
+  std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();<br>
+<br>
+  if (!XarMemberName.empty())<br>
+    outs() << "In xar member " << XarMemberName << ": ";<br>
+  else<br>
+    outs() << "For (__LLVM,__bundle) section: ";<br>
+  outs() << "xar table of contents:\n";<br>
+  outs() << Buffer->getBuffer() << "\n";<br>
+<br>
+  // TODO: Go through the xar's files.<br>
+  xar_iter_t xi = xar_iter_new();<br>
+  if(!xi){<br>
+    errs() << "Can't obtain an xar iterator for xar archive "<br>
+           << XarFilename.c_str() << "\n";<br>
+    xar_close(xar);<br>
+    return;<br>
+  }<br>
+  for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){<br>
+    const char *key;<br>
+    xar_iter_t xp;<br>
+    const char *member_name, *member_type, *member_size_string;<br>
+    size_t member_size;<br>
+<br>
+    xp = xar_iter_new();<br>
+    if(!xp){<br>
+      errs() << "Can't obtain an xar iterator for xar archive "<br>
+            << XarFilename.c_str() << "\n";<br>
+      xar_close(xar);<br>
+      return;<br>
+    }<br>
+    member_name = NULL;<br>
+    member_type = NULL;<br>
+    member_size_string = NULL;<br>
+    for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){<br>
+      const char *val = nullptr;<br>
+      xar_prop_get(xf, key, &val);<br>
+#if 0 // Useful for debugging.<br>
+      outs() << "key: " << key << " value: " << val << "\n";<br>
+#endif<br>
+      if(strcmp(key, "name") == 0)<br>
+       member_name = val;<br>
+      if(strcmp(key, "type") == 0)<br>
+       member_type = val;<br>
+      if(strcmp(key, "data/size") == 0)<br>
+       member_size_string = val;<br>
+    }<br>
+    /*<br>
+     * If we find a file with a name, date/size and type properties<br>
+     * and with the type being "file" see if that is a xar file.<br>
+     */<br>
+    if (member_name != NULL && member_type != NULL &&<br>
+        strcmp(member_type, "file") == 0 &&<br>
+        member_size_string != NULL){<br>
+      // Extract the file into a buffer.<br>
+      char *endptr;<br>
+      member_size = strtoul(member_size_string, &endptr, 10);<br>
+      if (*endptr == '\0' && member_size != 0) {<br>
+       char *buffer = (char *) ::operator new (member_size);<br>
+       if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {<br>
+#if 0 // Useful for debugging.<br>
+         outs() << "xar member: " << member_name << " extracted\n";<br>
+#endif<br>
+          // Set the XarMemberName we want to see printed in the header.<br>
+         std::string OldXarMemberName;<br>
+         // If XarMemberName is already set this is nested. So<br>
+         // save the old name and create the nested name.<br>
+         if (!XarMemberName.empty()) {<br>
+           OldXarMemberName = XarMemberName;<br>
+            XarMemberName =<br>
+             (Twine("[") + XarMemberName + "]" + member_name).str();<br>
+         } else {<br>
+           OldXarMemberName = "";<br>
+           XarMemberName = member_name;<br>
+         }<br>
+         // See if this is could be a xar file (nested).<br>
+         if (member_size >= sizeof(struct xar_header)) {<br>
+#if 0 // Useful for debugging.<br>
+           outs() << "could be a xar file: " << member_name << "\n";<br>
+#endif<br>
+           memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));<br>
+            if (sys::IsLittleEndianHost)<br>
+             swapStruct(XarHeader);<br>
+           if(XarHeader.magic == XAR_HEADER_MAGIC)<br>
+             DumpBitcodeSection(O, buffer, member_size, verbose,<br>
+                                 PrintXarHeader, PrintXarFileHeaders,<br>
+                                XarMemberName);<br>
+         }<br>
+         XarMemberName = OldXarMemberName;<br>
+       }<br>
+        delete buffer;<br>
+      }<br>
+    }<br>
+    xar_iter_free(xp);<br>
+  }<br>
+  xar_close(xar);<br>
+}<br>
+#endif // defined(HAVE_LIBXAR)<br>
+<br>
 static void printObjcMetaData(MachOObjectFile *O, bool verbose) {<br>
   if (O->is64Bit())<br>
     printObjc2_64bit_MetaData(O, verbose);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>
</div></blockquote></div><br></div></div></div></blockquote></div><br></div></div>
_______________________________________________<br>llvm-commits mailing list<br><a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br></div></blockquote></div><br></div></div></div></div></blockquote></div><br></div></div>