llvm.org GIT mirror llvm / 866cdd5
Add the printing the Mach-O (__LLVM,__bundle) xar archive file section "verbosely" to llvm-objdump. This section is created with -fembed-bitcode option. This requires the use of libxar and the Cmake and lit support were crafted by Chris Bieneman! rdar://26202242 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270491 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 4 years ago
8 changed file(s) with 457 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
138138 else()
139139 set(HAVE_TERMINFO 0)
140140 endif()
141 endif()
142
143 check_library_exists(xar xar_open "" HAVE_LIBXAR)
144 if(HAVE_LIBXAR)
145 set(XAR_LIB xar)
141146 endif()
142147
143148 # function checks
320320
321321 /* Define if the setupterm() function is supported this platform. */
322322 #cmakedefine HAVE_TERMINFO ${HAVE_TERMINFO}
323
324 /* Define if the xar_open() function is supported this platform. */
325 #cmakedefine HAVE_LIBXAR ${HAVE_LIBXAR}
323326
324327 /* Define to 1 if you have the header file. */
325328 #cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
2020
2121 DEPENDS
2222 intrinsics_gen
23
24 LINK_LIBS ${XAR_LIB}
2325 )
496496 if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
497497 config.available_features.add('global-isel')
498498 llvm_config_cmd.wait()
499
500 if config.have_libxar:
501 config.available_features.add('xar')
3333 config.llvm_use_intel_jitevents = "@LLVM_USE_INTEL_JITEVENTS@"
3434 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
3535 config.have_zlib = "@HAVE_LIBZ@"
36 config.have_libxar = "@HAVE_LIBXAR@"
3637 config.have_dia_sdk = @HAVE_DIA_SDK@
3738 config.enable_ffi = "@LLVM_ENABLE_FFI@"
3839 config.test_examples = "@ENABLE_EXAMPLES@"
0 # REQUIRES: xar
1 # RUN: llvm-objdump -macho -archive-headers -section __LLVM,__bundle %p/Inputs/LLVM-bundle.macho-x86_64 | FileCheck %s
2
3 # CHECK: For (__LLVM,__bundle) section: xar header
4 # CHECK: magic XAR_HEADER_MAGIC
5 # CHECK: size 28
6 # CHECK: version 1
7 # CHECK: toc_length_compressed 542
8 # CHECK: toc_length_uncompressed 1250
9 # CHECK: cksum_alg XAR_CKSUM_SHA1
10 # CHECK: For (__LLVM,__bundle) section: xar archive files:
11 # CHECK: 1664 1
12 # CHECK: For (__LLVM,__bundle) section: xar table of contents:
13 # CHECK:
14 # CHECK:
15 # CHECK:
16 # CHECK: 1.0
17 # CHECK: x86_64
18 # CHECK: MacOSX
19 # CHECK: 10.11.0
20 # CHECK:
21 # CHECK: libSystem.dylib
22 # CHECK:
23 # CHECK:
24 # CHECK:
25 # CHECK:
26 # CHECK:
27 # CHECK:
28 # CHECK:
29 # CHECK:
30 # CHECK:
31 # CHECK:
32 # CHECK:
33 # CHECK:
34 # CHECK:
35 # CHECK: 20
36 # CHECK: 0
37 # CHECK:
38 # CHECK: 2016-05-23T20:49:10
39 # CHECK:
40 # CHECK: 1
41 # CHECK: file
42 # CHECK:
43 # CHECK: a319940ff5f5248ca8b44cf7b4b65e7dd49a47ab
44 # CHECK: a319940ff5f5248ca8b44cf7b4b65e7dd49a47ab
45 # CHECK: 1664
46 # CHECK: 20
47 # CHECK:
48 # CHECK: 1664
49 # CHECK:
50 # CHECK: Bitcode
51 # CHECK:
52 # CHECK: -triple
53 # CHECK: x86_64-apple-macosx10.11.0
54 # CHECK: -emit-obj
55 # CHECK: -disable-llvm-optzns
56 # CHECK:
57 # CHECK:
58 # CHECK:
59 # CHECK:
4141 #include "llvm/Support/MemoryBuffer.h"
4242 #include "llvm/Support/TargetRegistry.h"
4343 #include "llvm/Support/TargetSelect.h"
44 #include "llvm/Support/ToolOutputFile.h"
4445 #include "llvm/Support/raw_ostream.h"
4546 #include
4647 #include
4849
4950 #if HAVE_CXXABI_H
5051 #include
52 #endif
53
54 #ifdef HAVE_LIBXAR
55 extern "C" {
56 #include
57 }
5158 #endif
5259
5360 using namespace llvm;
10401047 StringRef DisSegName, StringRef DisSectName);
10411048 static void DumpProtocolSection(MachOObjectFile *O, const char *sect,
10421049 uint32_t size, uint32_t addr);
1050 #ifdef HAVE_LIBXAR
1051 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
1052 uint32_t size, bool verbose,
1053 bool PrintXarHeader, bool PrintXarFileHeaders,
1054 std::string XarMemberName);
1055 #endif // defined(HAVE_LIBXAR)
10431056
10441057 static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
10451058 bool verbose) {
11011114 DumpProtocolSection(O, sect, sect_size, sect_addr);
11021115 continue;
11031116 }
1117 #ifdef HAVE_LIBXAR
1118 if (SegName == "__LLVM" && SectName == "__bundle") {
1119 DumpBitcodeSection(O, sect, sect_size, verbose, !NoSymbolicOperands,
1120 ArchiveHeaders, "");
1121 continue;
1122 }
1123 #endif // defined(HAVE_LIBXAR)
11041124 switch (section_type) {
11051125 case MachO::S_REGULAR:
11061126 DumpRawSectionContents(O, sect, sect_size, sect_addr);
56435663 outs() << "(not in an __OBJC section)\n";
56445664 }
56455665 }
5666
5667 #ifdef HAVE_LIBXAR
5668 inline void swapStruct(struct xar_header &xar) {
5669 sys::swapByteOrder(xar.magic);
5670 sys::swapByteOrder(xar.size);
5671 sys::swapByteOrder(xar.version);
5672 sys::swapByteOrder(xar.toc_length_compressed);
5673 sys::swapByteOrder(xar.toc_length_uncompressed);
5674 sys::swapByteOrder(xar.cksum_alg);
5675 }
5676
5677 static void PrintModeVerbose(uint32_t mode) {
5678 switch(mode & S_IFMT){
5679 case S_IFDIR:
5680 outs() << "d";
5681 break;
5682 case S_IFCHR:
5683 outs() << "c";
5684 break;
5685 case S_IFBLK:
5686 outs() << "b";
5687 break;
5688 case S_IFREG:
5689 outs() << "-";
5690 break;
5691 case S_IFLNK:
5692 outs() << "l";
5693 break;
5694 case S_IFSOCK:
5695 outs() << "s";
5696 break;
5697 default:
5698 outs() << "?";
5699 break;
5700 }
5701
5702 /* owner permissions */
5703 if(mode & S_IREAD)
5704 outs() << "r";
5705 else
5706 outs() << "-";
5707 if(mode & S_IWRITE)
5708 outs() << "w";
5709 else
5710 outs() << "-";
5711 if(mode & S_ISUID)
5712 outs() << "s";
5713 else if(mode & S_IEXEC)
5714 outs() << "x";
5715 else
5716 outs() << "-";
5717
5718 /* group permissions */
5719 if(mode & (S_IREAD >> 3))
5720 outs() << "r";
5721 else
5722 outs() << "-";
5723 if(mode & (S_IWRITE >> 3))
5724 outs() << "w";
5725 else
5726 outs() << "-";
5727 if(mode & S_ISGID)
5728 outs() << "s";
5729 else if(mode & (S_IEXEC >> 3))
5730 outs() << "x";
5731 else
5732 outs() << "-";
5733
5734 /* other permissions */
5735 if(mode & (S_IREAD >> 6))
5736 outs() << "r";
5737 else
5738 outs() << "-";
5739 if(mode & (S_IWRITE >> 6))
5740 outs() << "w";
5741 else
5742 outs() << "-";
5743 if(mode & S_ISVTX)
5744 outs() << "t";
5745 else if(mode & (S_IEXEC >> 6))
5746 outs() << "x";
5747 else
5748 outs() << "-";
5749 }
5750
5751 static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
5752 xar_iter_t xi;
5753 xar_file_t xf;
5754 xar_iter_t xp;
5755 const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;
5756 char *endp;
5757 uint32_t mode_value;
5758
5759 xi = xar_iter_new();
5760 if (!xi) {
5761 errs() << "Can't obtain an xar iterator for xar archive "
5762 << XarFilename << "\n";
5763 return;
5764 }
5765
5766 // Go through the xar's files.
5767 for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {
5768 xp = xar_iter_new();
5769 if(!xp){
5770 errs() << "Can't obtain an xar iterator for xar archive "
5771 << XarFilename << "\n";
5772 return;
5773 }
5774 type = nullptr;
5775 mode = nullptr;
5776 user = nullptr;
5777 group = nullptr;
5778 size = nullptr;
5779 mtime = nullptr;
5780 name = nullptr;
5781 for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5782 const char *val = nullptr;
5783 xar_prop_get(xf, key, &val);
5784 #if 0 // Useful for debugging.
5785 outs() << "key: " << key << " value: " << val << "\n";
5786 #endif
5787 if(strcmp(key, "type") == 0)
5788 type = val;
5789 if(strcmp(key, "mode") == 0)
5790 mode = val;
5791 if(strcmp(key, "user") == 0)
5792 user = val;
5793 if(strcmp(key, "group") == 0)
5794 group = val;
5795 if(strcmp(key, "data/size") == 0)
5796 size = val;
5797 if(strcmp(key, "mtime") == 0)
5798 mtime = val;
5799 if(strcmp(key, "name") == 0)
5800 name = val;
5801 }
5802 if(mode != nullptr){
5803 mode_value = strtoul(mode, &endp, 8);
5804 if(*endp != '\0')
5805 outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";
5806 if(strcmp(type, "file") == 0)
5807 mode_value |= S_IFREG;
5808 PrintModeVerbose(mode_value);
5809 outs() << " ";
5810 }
5811 if(user != nullptr)
5812 outs() << format("%10s/", user);
5813 if(group != nullptr)
5814 outs() << format("%-10s ", group);
5815 if(size != nullptr)
5816 outs() << format("%7s ", size);
5817 if(mtime != nullptr){
5818 for(m = mtime; *m != 'T' && *m != '\0'; m++)
5819 outs() << *m;
5820 if(*m == 'T')
5821 m++;
5822 outs() << " ";
5823 for( ; *m != 'Z' && *m != '\0'; m++)
5824 outs() << *m;
5825 outs() << " ";
5826 }
5827 if(name != nullptr)
5828 outs() << name;
5829 outs() << "\n";
5830 }
5831 }
5832
5833 static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
5834 uint32_t size, bool verbose,
5835 bool PrintXarHeader, bool PrintXarFileHeaders,
5836 std::string XarMemberName) {
5837 if(size < sizeof(struct xar_header)) {
5838 outs() << "size of (__LLVM,__bundle) section too small (smaller than size "
5839 "of struct xar_header)\n";
5840 return;
5841 }
5842 struct xar_header XarHeader;
5843 memcpy(&XarHeader, sect, sizeof(struct xar_header));
5844 if (sys::IsLittleEndianHost)
5845 swapStruct(XarHeader);
5846 if (PrintXarHeader) {
5847 if (!XarMemberName.empty())
5848 outs() << "In xar member " << XarMemberName << ": ";
5849 else
5850 outs() << "For (__LLVM,__bundle) section: ";
5851 outs() << "xar header\n";
5852 if (XarHeader.magic == XAR_HEADER_MAGIC)
5853 outs() << " magic XAR_HEADER_MAGIC\n";
5854 else
5855 outs() << " magic "
5856 << format_hex(XarHeader.magic, 10, true)
5857 << " (not XAR_HEADER_MAGIC)\n";
5858 outs() << " size " << XarHeader.size << "\n";
5859 outs() << " version " << XarHeader.version << "\n";
5860 outs() << " toc_length_compressed " << XarHeader.toc_length_compressed
5861 << "\n";
5862 outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed
5863 << "\n";
5864 outs() << " cksum_alg ";
5865 switch (XarHeader.cksum_alg) {
5866 case XAR_CKSUM_NONE:
5867 outs() << "XAR_CKSUM_NONE\n";
5868 break;
5869 case XAR_CKSUM_SHA1:
5870 outs() << "XAR_CKSUM_SHA1\n";
5871 break;
5872 case XAR_CKSUM_MD5:
5873 outs() << "XAR_CKSUM_MD5\n";
5874 break;
5875 case XAR_CKSUM_SHA256:
5876 outs() << "XAR_CKSUM_SHA256\n";
5877 break;
5878 case XAR_CKSUM_SHA512:
5879 outs() << "XAR_CKSUM_SHA512\n";
5880 break;
5881 default:
5882 outs() << XarHeader.cksum_alg << "\n";
5883 }
5884 }
5885
5886 SmallString<128> XarFilename;
5887 int FD;
5888 std::error_code XarEC =
5889 sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);
5890 if (XarEC) {
5891 errs() << XarEC.message() << "\n";
5892 return;
5893 }
5894 tool_output_file XarFile(XarFilename, FD);
5895 raw_fd_ostream &XarOut = XarFile.os();
5896 StringRef XarContents(sect, size);
5897 XarOut << XarContents;
5898 XarOut.close();
5899 if (XarOut.has_error())
5900 return;
5901
5902 xar_t xar = xar_open(XarFilename.c_str(), READ);
5903 if (!xar) {
5904 errs() << "Can't create temporary xar archive " << XarFilename << "\n";
5905 return;
5906 }
5907
5908 SmallString<128> TocFilename;
5909 std::error_code TocEC =
5910 sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);
5911 if (TocEC) {
5912 errs() << TocEC.message() << "\n";
5913 return;
5914 }
5915 xar_serialize(xar, TocFilename.c_str());
5916
5917 if (PrintXarFileHeaders) {
5918 if (!XarMemberName.empty())
5919 outs() << "In xar member " << XarMemberName << ": ";
5920 else
5921 outs() << "For (__LLVM,__bundle) section: ";
5922 outs() << "xar archive files:\n";
5923 PrintXarFilesSummary(XarFilename.c_str(), xar);
5924 }
5925
5926 ErrorOr> FileOrErr =
5927 MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());
5928 if (std::error_code EC = FileOrErr.getError()) {
5929 errs() << EC.message() << "\n";
5930 return;
5931 }
5932 std::unique_ptr &Buffer = FileOrErr.get();
5933
5934 if (!XarMemberName.empty())
5935 outs() << "In xar member " << XarMemberName << ": ";
5936 else
5937 outs() << "For (__LLVM,__bundle) section: ";
5938 outs() << "xar table of contents:\n";
5939 outs() << Buffer->getBuffer() << "\n";
5940
5941 // TODO: Go through the xar's files.
5942 xar_iter_t xi = xar_iter_new();
5943 if(!xi){
5944 errs() << "Can't obtain an xar iterator for xar archive "
5945 << XarFilename.c_str() << "\n";
5946 xar_close(xar);
5947 return;
5948 }
5949 for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){
5950 const char *key;
5951 xar_iter_t xp;
5952 const char *member_name, *member_type, *member_size_string;
5953 size_t member_size;
5954
5955 xp = xar_iter_new();
5956 if(!xp){
5957 errs() << "Can't obtain an xar iterator for xar archive "
5958 << XarFilename.c_str() << "\n";
5959 xar_close(xar);
5960 return;
5961 }
5962 member_name = NULL;
5963 member_type = NULL;
5964 member_size_string = NULL;
5965 for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5966 const char *val = nullptr;
5967 xar_prop_get(xf, key, &val);
5968 #if 0 // Useful for debugging.
5969 outs() << "key: " << key << " value: " << val << "\n";
5970 #endif
5971 if(strcmp(key, "name") == 0)
5972 member_name = val;
5973 if(strcmp(key, "type") == 0)
5974 member_type = val;
5975 if(strcmp(key, "data/size") == 0)
5976 member_size_string = val;
5977 }
5978 /*
5979 * If we find a file with a name, date/size and type properties
5980 * and with the type being "file" see if that is a xar file.
5981 */
5982 if (member_name != NULL && member_type != NULL &&
5983 strcmp(member_type, "file") == 0 &&
5984 member_size_string != NULL){
5985 // Extract the file into a buffer.
5986 char *endptr;
5987 member_size = strtoul(member_size_string, &endptr, 10);
5988 if (*endptr == '\0' && member_size != 0) {
5989 char *buffer = (char *) ::operator new (member_size);
5990 if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {
5991 #if 0 // Useful for debugging.
5992 outs() << "xar member: " << member_name << " extracted\n";
5993 #endif
5994 // Set the XarMemberName we want to see printed in the header.
5995 std::string OldXarMemberName;
5996 // If XarMemberName is already set this is nested. So
5997 // save the old name and create the nested name.
5998 if (!XarMemberName.empty()) {
5999 OldXarMemberName = XarMemberName;
6000 XarMemberName =
6001 (Twine("[") + XarMemberName + "]" + member_name).str();
6002 } else {
6003 OldXarMemberName = "";
6004 XarMemberName = member_name;
6005 }
6006 // See if this is could be a xar file (nested).
6007 if (member_size >= sizeof(struct xar_header)) {
6008 #if 0 // Useful for debugging.
6009 outs() << "could be a xar file: " << member_name << "\n";
6010 #endif
6011 memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));
6012 if (sys::IsLittleEndianHost)
6013 swapStruct(XarHeader);
6014 if(XarHeader.magic == XAR_HEADER_MAGIC)
6015 DumpBitcodeSection(O, buffer, member_size, verbose,
6016 PrintXarHeader, PrintXarFileHeaders,
6017 XarMemberName);
6018 }
6019 XarMemberName = OldXarMemberName;
6020 }
6021 delete buffer;
6022 }
6023 }
6024 xar_iter_free(xp);
6025 }
6026 xar_close(xar);
6027 }
6028 #endif // defined(HAVE_LIBXAR)
56466029
56476030 static void printObjcMetaData(MachOObjectFile *O, bool verbose) {
56486031 if (O->is64Bit())