this repo has no description
at fixPythonPipStalling 182 lines 4.4 kB view raw
1/* 2This file is part of Darling. 3 4Copyright (C) 2018-2020 Lubos Dolezel 5 6Darling is free software: you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation, either version 3 of the License, or 9(at your option) any later version. 10 11Darling is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with Darling. If not, see <http://www.gnu.org/licenses/>. 18*/ 19#include <stdio.h> 20#include <unistd.h> 21#include <fcntl.h> 22#include <sys/mman.h> 23#include <stdint.h> 24#include <stdbool.h> 25#include <stdlib.h> 26#include <mach-o/loader.h> 27#include <mach-o/fat.h> 28#include <string.h> 29#include <errno.h> 30 31bool printElfdepAny(const void* mem); 32bool printElfdepMH(const struct mach_header* mhdr); 33bool printElfdepMH64(const struct mach_header_64* mhdr); 34bool printFat(const struct fat_header* fhdr); 35bool printTaf(const struct fat_header* fhdr); 36 37int main(int argc, const char** argv) 38{ 39 if (argc != 2) 40 { 41 fprintf(stderr, "elfdep: Prints the ELF dependency (SONAME) of a Mach-O file, if any\n"); 42 fprintf(stderr, "Usage: elfdep <macho-file>\n"); 43 return EXIT_FAILURE; 44 } 45 46 int fd = open(argv[1], O_RDONLY); 47 if (fd == -1) 48 { 49 fprintf(stderr, "Cannot open %s: %s", argv[1], strerror(errno)); 50 return EXIT_FAILURE; 51 } 52 53 size_t length = lseek(fd, 0, SEEK_END); 54 55 void* mem = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0); 56 if (mem == MAP_FAILED) 57 { 58 perror("mmap"); 59 return EXIT_FAILURE; 60 } 61 62 close(fd); 63 64 printElfdepAny(mem); 65 66 munmap(mem, length); 67 68 return EXIT_SUCCESS; 69} 70 71bool printElfdepAny(const void* mem) 72{ 73 const struct mach_header* mhdr = (struct mach_header*) mem; 74 75 if (mhdr->magic == MH_MAGIC) 76 return printElfdepMH(mhdr); 77 else if (mhdr->magic == MH_MAGIC_64) 78 return printElfdepMH64((struct mach_header_64*) mhdr); 79 else if (mhdr->magic == FAT_MAGIC) 80 return printFat((struct fat_header*) mhdr); 81 else if (mhdr->magic == FAT_CIGAM) 82 return printTaf((struct fat_header*) mhdr); 83 else 84 { 85 fprintf(stderr, "File format not recognized\n"); 86 exit(1); 87 } 88} 89 90bool printElfdep(const struct load_command* lc, const void* base) 91{ 92 if (lc->cmd == LC_SEGMENT) 93 { 94 const struct segment_command* sc = (const struct segment_command*) lc; 95 96 if (strcmp(sc->segname, "__TEXT") == 0) 97 { 98 const struct section* sect = (const struct section*)(sc+1); 99 for (int i = 0; i < sc->nsects; i++) 100 { 101 if (strcmp(sect->sectname, "__elfname") == 0) 102 { 103 printf("%s\n", ((const char*)base) + sect->offset); 104 return true; 105 } 106 sect++; 107 } 108 } 109 } 110 else if (lc->cmd == LC_SEGMENT_64) 111 { 112 const struct segment_command_64* sc = (const struct segment_command_64*) lc; 113 114 if (strcmp(sc->segname, "__TEXT") == 0) 115 { 116 const struct section_64* sect = (const struct section_64*)(sc+1); 117 for (int i = 0; i < sc->nsects; i++) 118 { 119 if (strcmp(sect->sectname, "__elfname") == 0) 120 { 121 printf("%s\n", ((const char*)base) + sect->offset); 122 return true; 123 } 124 sect++; 125 } 126 } 127 } 128 return false; 129} 130 131bool printElfdepMH(const struct mach_header* mhdr) 132{ 133 const uint8_t* command = (const uint8_t*)(mhdr + 1); 134 for (uint32_t i = 0; i < mhdr->ncmds; i++) 135 { 136 if (printElfdep((const struct load_command*) command, mhdr)) 137 return true; 138 else 139 command += ((const struct load_command*)command)->cmdsize; 140 } 141 return false; 142} 143 144bool printElfdepMH64(const struct mach_header_64* mhdr) 145{ 146 const uint8_t* command = (const uint8_t*)(mhdr + 1); 147 for (uint32_t i = 0; i < mhdr->ncmds; i++) 148 { 149 if (printElfdep((const struct load_command*) command, mhdr)) 150 return true; 151 else 152 command += ((const struct load_command*)command)->cmdsize; 153 } 154 return false; 155} 156 157bool printFat(const struct fat_header* fhdr) 158{ 159 const struct fat_arch* fa = ((const struct fat_arch*) (fhdr+1)); 160 161 for (uint32_t i = 0; i < fhdr->nfat_arch; i++) 162 { 163 if (printElfdepAny(((char*) fhdr) + fa[i].offset)) 164 return true; 165 } 166 167 return false; 168} 169 170bool printTaf(const struct fat_header* fhdr) 171{ 172 const struct fat_arch* fa = ((const struct fat_arch*) (fhdr+1)); 173 174 for (uint32_t i = 0; i < __builtin_bswap32(fhdr->nfat_arch); i++) 175 { 176 if (printElfdepAny(((char*) fhdr) + __builtin_bswap32(fa[i].offset))) 177 return true; 178 } 179 180 return false; 181} 182