this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add print_wrapped_elf tool (useful when packaging into DEB/RPM)

+188
+6
src/startup/CMakeLists.txt
··· 51 51 setcap(libexec/darling/bin/mldr cap_sys_rawio+ep) 52 52 setcap(libexec/darling/bin/mldr32 cap_sys_rawio+ep) 53 53 54 + # This tool is useful for packaging to detect ELF dependencies inside Mach-O libraries, 55 + # which standard distro tools cannot do. 56 + if (DEFINED WITH_PRINT_WRAPPED_ELF) 57 + add_executable(print_wrapped_elf wrapgen/print_wrapped_elf.cpp) 58 + endif (DEFINED WITH_PRINT_WRAPPED_ELF) 59 +
+182
src/startup/wrapgen/print_wrapped_elf.cpp
··· 1 + #include <mach-o/loader.h> 2 + #include <mach-o/fat.h> 3 + #include <iostream> 4 + #include <stdexcept> 5 + #include <sstream> 6 + #include <cstring> 7 + #include <stdlib.h> 8 + #include <unistd.h> 9 + #include <fcntl.h> 10 + #include <errno.h> 11 + 12 + #define CPU_ARCH_ABI64 0x01000000 13 + 14 + static void load(const char* path); 15 + 16 + int main(int argc, const char** argv) 17 + { 18 + if (argc != 2) 19 + { 20 + std::cerr << "Prints the name of the ELF library referenced by given Mach-O library.\n\n" 21 + "Usage: print_wrapped_elf <mach-o file>\n"; 22 + return 1; 23 + } 24 + 25 + try 26 + { 27 + load(argv[1]); 28 + } 29 + catch (const std::exception& e) 30 + { 31 + std::cerr << "When processing " << argv[1] << ": " << e.what() << std::endl; 32 + return 1; 33 + } 34 + return 0; 35 + } 36 + 37 + static void throwErrno(const char* msg) 38 + { 39 + std::stringstream ss; 40 + ss << msg << ": " << strerror(errno); 41 + throw std::runtime_error(ss.str()); 42 + } 43 + 44 + template<typename mhdr_type, typename section_type, int seg_cmd, typename segment_type> 45 + void parseMachO(int fd) 46 + { 47 + mhdr_type header; 48 + uint8_t* cmds; 49 + unsigned long fat_offset; 50 + 51 + fat_offset = lseek(fd, 0, SEEK_CUR); 52 + 53 + if (read(fd, &header, sizeof(header)) != sizeof(header)) 54 + throwErrno("Cannot read the mach header"); 55 + 56 + cmds = new uint8_t[header.sizeofcmds]; 57 + 58 + if (read(fd, cmds, header.sizeofcmds) != header.sizeofcmds) 59 + throwErrno("Cannot read loader commands"); 60 + 61 + for (uint32_t i = 0, p = 0; i < header.ncmds; i++) 62 + { 63 + load_command* lc; 64 + 65 + lc = (load_command*) &cmds[p]; 66 + 67 + if (lc->cmd == seg_cmd) 68 + { 69 + segment_type* seg = (segment_type*) lc; 70 + 71 + if (strcmp(seg->segname, "__TEXT") == 0) 72 + { 73 + section_type* sect = (section_type*) (seg+1); 74 + section_type* end = (section_type*) (&cmds[p + lc->cmdsize]); 75 + 76 + while (sect < end) 77 + { 78 + if (strcmp(sect->sectname, "__elfname") == 0) 79 + { 80 + char* text; 81 + 82 + if (sect->size > 100) 83 + throw std::runtime_error("__TEXT,__elfname section has unusual length"); 84 + 85 + text = new char[sect->size]; 86 + 87 + if (pread(fd, text, sect->size, sect->offset + fat_offset) != sect->size) 88 + throwErrno("Cannot read __elfname section"); 89 + 90 + if (text[sect->size-1] != 0) 91 + throw std::runtime_error("__TEXT,__elfname section contents don't look like a string"); 92 + 93 + std::cout << text << std::endl; 94 + delete [] text; 95 + } 96 + sect++; 97 + } 98 + } 99 + } 100 + 101 + p += lc->cmdsize; 102 + } 103 + 104 + delete [] cmds; 105 + } 106 + 107 + void parseMachO32(int fd) 108 + { 109 + parseMachO<mach_header, section, LC_SEGMENT, segment_command>(fd); 110 + } 111 + 112 + void parseMachO64(int fd) 113 + { 114 + parseMachO<mach_header_64, section_64, LC_SEGMENT_64, segment_command_64>(fd); 115 + } 116 + 117 + static void load(const char* path) 118 + { 119 + int fd; 120 + uint32_t magic; 121 + 122 + fd = open(path, O_RDONLY); 123 + if (fd == -1) 124 + throwErrno("Cannot open the file"); 125 + 126 + if (read(fd, &magic, sizeof(magic)) != sizeof(magic)) 127 + throwErrno("Cannot read file header"); 128 + 129 + if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) 130 + { 131 + lseek(fd, 0, SEEK_SET); 132 + parseMachO64(fd); 133 + } 134 + else if (magic == MH_MAGIC || magic == MH_CIGAM) 135 + { 136 + lseek(fd, 0, SEEK_SET); 137 + parseMachO32(fd); 138 + } 139 + else if (magic == FAT_MAGIC || magic == FAT_CIGAM) 140 + { 141 + struct fat_header fhdr; 142 + const bool swap = magic == FAT_CIGAM; 143 + 144 + #define SWAP32(x) x = __bswap_32(x) 145 + 146 + if (read(fd, &fhdr.nfat_arch, sizeof(fhdr.nfat_arch)) != sizeof(fhdr.nfat_arch)) 147 + throwErrno("Cannot read file header"); 148 + 149 + if (swap) 150 + SWAP32(fhdr.nfat_arch); 151 + 152 + for (uint32_t i = 0; i < fhdr.nfat_arch; i++) 153 + { 154 + struct fat_arch arch; 155 + 156 + if (read(fd, &arch, sizeof(arch)) != sizeof(arch)) 157 + throwErrno("Cannot read fat_arch header"); 158 + 159 + if (swap) 160 + { 161 + SWAP32(arch.cputype); 162 + SWAP32(arch.cpusubtype); 163 + SWAP32(arch.offset); 164 + SWAP32(arch.size); 165 + SWAP32(arch.align); 166 + } 167 + 168 + if (lseek(fd, arch.offset, SEEK_SET) == -1) 169 + throwErrno("Cannot seek to selected arch in fat"); 170 + 171 + if (arch.cputype & CPU_ARCH_ABI64) 172 + parseMachO64(fd); 173 + else 174 + parseMachO32(fd); 175 + 176 + break; 177 + } 178 + } 179 + 180 + ::close(fd); 181 + } 182 +