<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></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 25, 2016, at 3:13 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 Wed, May 25, 2016 at 2:56 PM, Chris Bieneman <span dir="ltr" class=""><<a href="mailto:beanz@apple.com" target="_blank" class="">beanz@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Sean,<div class=""><br class=""></div><div class="">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" class="">opensource.apple.com</a> here:</div><div class=""><br class=""></div><div class=""><a href="https://opensource.apple.com/source/ld64/ld64-253.9/src/ld/passes/bitcode_bundle.cpp" target="_blank" class="">https://opensource.apple.com/source/ld64/ld64-253.9/src/ld/passes/bitcode_bundle.cpp</a></div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">Does this address your concerns about the timeline for introducing this patch?</div></div></blockquote><div class=""><br class=""></div><div class="">Yes. But it doesn't address the lack of tests ;)</div></div></div></div></div></blockquote><div><br class=""></div><div>We can certainly add more tests. I do think the one Kevin added is actually really great. It covers all the functionality added and is very representative of a real-world case. Personally I’m not sure that adding additional tests would actually increase test coverage, but Kevin would know better than I.</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 add this code in more incrementally than just a patch dump with a single sanity check test case? </div></div></div></div></div></blockquote><div><br class=""></div><div>Yea, I agree this patch is larger than probably should have been added in a single patch, but since it is in now and doesn’t have any real problems, can we just agree to not land large patches like this again in the future?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">There's also numerous violations of the coding standard for variable names.</div></div></div></div></div></blockquote><div><br class=""></div><div>I’m kinda conflicted on this. On the one hand, yea it doesn’t conform to our style guidelines. On the other hand, neither does most of the code in the source file, and the code is interfacing with C APIs and struct definitions that are from outside LLVM and use underscore separated naming. As a result this source file does have a largely consistent style, which I think is important.</div><div><br class=""></div><div>We should probably do a cleanup pass across the whole file to correct variable names to camel case though to match LLVM convention.</div><div><br class=""></div><div>-Chris</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"><div style="word-wrap:break-word" class=""><span class="HOEnZb"><font color="#888888" class=""><div class=""><br class=""></div><div class="">-Chris</div></font></span><div class=""><div class="h5"><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On May 25, 2016, at 1:16 PM, Sean Silva via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, May 25, 2016 at 10:55 AM, Kevin Enderby <span dir="ltr" class=""><<a href="mailto:enderby@apple.com" target="_blank" class="">enderby@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On May 24, 2016, at 7:27 PM, Sean Silva <<a href="mailto:chisophugis@gmail.com" target="_blank" class="">chisophugis@gmail.com</a>> wrote:</div><br class=""><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 class=""><br class=""></div></span>This exists today with the clang compilers Apple ships.</div></div></blockquote><div class=""><br class=""></div><div class="">I think it makes sense to add when that feature is upstream.</div><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"><div style="word-wrap:break-word" class=""><div class=""><span class=""><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 class=""><br class=""></div></span>The test case below was created with the Apple shipping compiler with:</div><div class=""><br class=""></div><div class="">cc -o LLVM-bundle.macho-x86_64 hello.c -fembed-bitcode</div><div class=""><br class=""></div><div class="">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 class=""><div class=""><div class=""><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 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" target="_blank" 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=""></div></div></div></blockquote></div><br class=""></div></div>
_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class=""></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>