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