this repo has no description
1
fork

Configure Feed

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

Loads of work on dyld and BSD functions

+693 -692
+1 -1
.gdbinit
··· 27 27 28 28 set follow-fork-mode child 29 29 30 - python sys.path.insert(0, '.') 30 + python sys.path.insert(0, './tools/') 31 31 python import gdb_maloader 32 32 33 33 define mreload
+1 -1
CMakeLists.txt
··· 53 53 54 54 add_executable(fatmacho-extract ${fatmacho-extract_SRCS}) 55 55 56 - target_link_libraries(fatmacho-extract -ldl -lpthread mach-o) 56 + target_link_libraries(fatmacho-extract -ldl -lpthread mach-o -Wl,-export-dynamic) 57 57 58 58 install(TARGETS dyld fatmacho-extract DESTINATION bin) 59 59
+21 -7
src/dyld/MachOLoader.cpp
··· 165 165 // __darwin_dlopen checks if already loaded 166 166 // automatically adds a reference if so 167 167 168 - if (!__darwin_dlopen(dylib.c_str(), DARWIN_RTLD_GLOBAL)) 169 - throw std::runtime_error("Cannot load " + dylib + "!"); 168 + if (!__darwin_dlopen(dylib.c_str(), DARWIN_RTLD_GLOBAL|DARWIN_RTLD_NOW)) 169 + { 170 + LOG << "Failed to dlopen " << dylib << ", throwing an exception\n"; 171 + std::stringstream ss; 172 + ss << "Cannot load " << dylib << ": " << __darwin_dlerror(); 173 + throw std::runtime_error(ss.str()); 174 + } 170 175 } 171 176 } 172 177 ··· 380 385 sym = reinterpret_cast<char*>(__darwin_dlsym(DARWIN_RTLD_DEFAULT, name.c_str())); 381 386 if (!sym) 382 387 { 383 - std::stringstream ss; 384 - ss << "Undefined symbol: " << name; 385 - throw std::runtime_error(ss.str()); 388 + const char* ign_sym = getenv("DYLD_IGN_MISSING_SYMS"); 389 + if (ign_sym && atoi(ign_sym)) 390 + { 391 + std::cerr << "!!! Undefined symbol: " << name << std::endl; 392 + sym = reinterpret_cast<char*>(undefinedFunction); 393 + } 394 + else 395 + { 396 + std::stringstream ss; 397 + ss << "Undefined symbol: " << name; 398 + throw std::runtime_error(ss.str()); 399 + } 386 400 } 387 - 388 - sym += bind->addend; 401 + else 402 + sym += bind->addend; 389 403 } 390 404 391 405 LOG << "bind " << name << ": "
+51 -13
src/dyld/dyld.cpp
··· 1 1 #include "MachO.h" 2 2 #include "MachOLoader.h" 3 3 #include "arch.h" 4 + #include "log.h" 4 5 #include <iostream> 5 6 #include <limits.h> 6 7 #include <cstdlib> 7 8 #include <stdexcept> 8 9 #include <cstring> 10 + #include <cassert> 9 11 10 12 char g_darwin_executable_path[PATH_MAX]; 11 13 char g_loader_path[PATH_MAX]; 14 + char g_sysroot[PATH_MAX] = ""; 15 + 12 16 MachO* g_mainBinary = 0; 13 17 MachOLoader* g_loader = 0; 14 18 int g_argc; 15 19 char** g_argv; 16 20 21 + static void autoSysrootSearch(); 22 + 17 23 int main(int argc, char** argv, char** envp) 18 24 { 19 25 if (argc == 1) 20 26 { 21 27 std::cerr << "This is Darwin dyld for " ARCH_NAME ". "; 22 - std::cerr << "Usage: " << argv[0] << " program-path [arguments...]\n"; 28 + std::cerr << "Usage: " << argv[0] << " program-path [arguments...]\n\n"; 29 + std::cerr << "Environment variables:\n" 30 + "\tDYLD_DEBUG=1 - enable debug info (lots of output)\n" 31 + "\tDYLD_IGN_MISSING_SYMS=1 - replace missing symbol references with a stub function\n" 32 + "\tDYLD_SYSROOT=<path> - set the base for library path resolution (overrides autodetection)\n"; 23 33 return 1; 24 34 } 25 35 ··· 35 45 //initDlfcn(); 36 46 37 47 g_mainBinary = MachO::readFile(argv[1], ARCH_NAME); 38 - #ifdef __x86_64__ 39 - if (!g_mainBinary->is64()) 48 + try 40 49 { 41 - std::cerr << argv[1] << ": Cannot execute binary file.\nThis version of Darwin dyld cannot run binaries for x86.\n"; 42 - return -ENOEXEC; 43 - } 50 + if (!g_mainBinary) 51 + throw std::runtime_error("Cannot open binary file"); 52 + #ifdef __x86_64__ 53 + if (!g_mainBinary->is64()) 54 + { 55 + std::cerr << argv[1] << ": Cannot execute binary file.\nThis version of Darwin dyld cannot run binaries for x86.\n"; 56 + return -ENOEXEC; 57 + } 44 58 #else 45 - if (g_mainBinary->is64()) 46 - { 47 - td::cerr << argv[1] << ": Cannot execute binary file.\nThis version of Darwin dyld cannot run binaries for x86-64.\n"; 48 - return -ENOEXEC; 49 - } 59 + if (g_mainBinary->is64()) 60 + { 61 + std::cerr << argv[1] << ": Cannot execute binary file.\nThis version of Darwin dyld cannot run binaries for x86-64.\n"; 62 + return -ENOEXEC; 63 + } 50 64 #endif 51 65 52 - try 53 - { 54 66 g_loader = new MachOLoader; 55 67 g_argv = argv+1; 56 68 g_argc = argc-1; 69 + 70 + autoSysrootSearch(); 71 + 57 72 g_loader->run(*g_mainBinary, argc-1, argv+1, envp); 58 73 59 74 delete g_loader; ··· 77 92 return g_loader_path; 78 93 } 79 94 95 + void autoSysrootSearch() 96 + { 97 + if (const char* s = getenv("DYLD_SYSROOT")) 98 + { 99 + strncpy(g_sysroot, s, PATH_MAX-1); 100 + g_sysroot[PATH_MAX-1] = 0; 101 + } 102 + else 103 + { 104 + std::string path = g_darwin_executable_path; 105 + size_t pos = path.rfind("/usr/"); 106 + 107 + LOG << "Looking for SYSROOT signs in " << g_darwin_executable_path << std::endl; 108 + 109 + if (pos != std::string::npos && pos > 0) 110 + { 111 + std::string sysroot = path.substr(0, pos); 112 + LOG << "SYSROOT detected to be " << sysroot << std::endl; 113 + strncpy(g_sysroot, sysroot.c_str(), PATH_MAX-1); 114 + g_sysroot[PATH_MAX-1] = 0; 115 + } 116 + } 117 + } 80 118
-470
src/dyld/ld-mac.cc
··· 1 - // Copyright 2011 Shinichiro Hamaji. All rights reserved. 2 - // 3 - // Redistribution and use in source and binary forms, with or without 4 - // modification, are permitted provided that the following conditions 5 - // are met: 6 - // 7 - // 1. Redistributions of source code must retain the above copyright 8 - // notice, this list of conditions and the following disclaimer. 9 - // 10 - // 2. Redistributions in binary form must reproduce the above 11 - // copyright notice, this list of conditions and the following 12 - // disclaimer in the documentation and/or other materials 13 - // provided with the distribution. 14 - // 15 - // THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY 16 - // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 - // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 - // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR 19 - // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 - // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 - // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 - // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 - // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 - // SUCH DAMAGE. 27 - 28 - // A Mach-O loader for linux. 29 - 30 - #include <assert.h> 31 - #include <dlfcn.h> 32 - #include <err.h> 33 - #include <errno.h> 34 - #include <execinfo.h> 35 - #include <fcntl.h> 36 - #include <limits.h> 37 - #include <memory> 38 - #include <signal.h> 39 - #include <stdio.h> 40 - #include <stdlib.h> 41 - #include <string.h> 42 - #include <sys/mman.h> 43 - #include <time.h> 44 - #include <ucontext.h> 45 - 46 - #include <algorithm> 47 - #include <iostream> 48 - #include <map> 49 - #include <set> 50 - #include <string> 51 - #include <tr1/unordered_map> 52 - #include <vector> 53 - 54 - #include "env_flags.h" 55 - #include "FatMachO.h" 56 - #include "log.h" 57 - #include "MachO.h" 58 - #include "FileMap.h" 59 - #include "arch.h" 60 - 61 - using namespace std; 62 - using namespace std::tr1; 63 - 64 - DEFINE_bool(TRACE_FUNCTIONS, false, "Show calling functions"); 65 - DEFINE_bool(PRINT_TIME, false, "Print time spent in this loader"); 66 - 67 - class MachO; 68 - 69 - static map<string, string> g_rename; 70 - static vector<string> g_bound_names; 71 - static set<string> g_no_trampoline; 72 - 73 - static FileMap g_file_map; 74 - 75 - static char* g_darwin_executable_path; 76 - 77 - static Timer g_timer; 78 - 79 - class MachOLoader; 80 - static MachOLoader* g_loader; 81 - 82 - /* 83 - static void initRename() { 84 - #define RENAME(src, dst) g_rename.insert(make_pair(#src, #dst)); 85 - #define WRAP(src) RENAME(src, __darwin_ ## src) 86 - #include "rename.tab" 87 - #undef RENAME 88 - #undef WRAP 89 - } 90 - */ 91 - 92 - 93 - 94 - 95 - 96 - 97 - 98 - class MachOLoader { 99 - #ifdef __x86_64__ 100 - typedef uint64_t intptr; 101 - typedef segment_command_64 Segment; 102 - 103 - static const vector<Segment*>& getSegments(const MachO& mach) { 104 - return mach.segments64(); 105 - } 106 - #else 107 - typedef uint32_t intptr; 108 - typedef segment_command Segment; 109 - 110 - static const vector<Segment*>& getSegments(const MachO& mach) { 111 - return mach.segments(); 112 - } 113 - #endif 114 - 115 - public: 116 - MachOLoader() 117 - : last_addr_(0) { 118 - // TODO: this is very wrong 119 - /* 120 - dylib_to_so_.insert(make_pair( 121 - "/System/Library/Frameworks/CoreFoundation.framework" 122 - "/Versions/A/CoreFoundation", 123 - "libCoreFoundation.so")); 124 - dylib_to_so_.insert(make_pair( 125 - "/usr/lib/libncurses.5.4.dylib", 126 - "libncurses.so")); 127 - 128 - symbol_to_so_.insert(make_pair("uuid_clear", "libuuid.so")); 129 - symbol_to_so_.insert(make_pair("uuid_compare", "libuuid.so")); 130 - symbol_to_so_.insert(make_pair("uuid_copy", "libuuid.so")); 131 - symbol_to_so_.insert(make_pair("uuid_generate", "libuuid.so")); 132 - symbol_to_so_.insert(make_pair("uuid_generate_random", "libuuid.so")); 133 - symbol_to_so_.insert(make_pair("uuid_generate_time", "libuuid.so")); 134 - symbol_to_so_.insert(make_pair("uuid_is_null", "libuuid.so")); 135 - symbol_to_so_.insert(make_pair("uuid_pack", "libuuid.so")); 136 - symbol_to_so_.insert(make_pair("uuid_parse", "libuuid.so")); 137 - symbol_to_so_.insert(make_pair("uuid_unpack", "libuuid.so")); 138 - symbol_to_so_.insert(make_pair("uuid_unparse", "libuuid.so")); 139 - symbol_to_so_.insert(make_pair("uuid_unparse_lower", "libuuid.so")); 140 - symbol_to_so_.insert(make_pair("uuid_unparse_upper", "libuuid.so")); 141 - */ 142 - 143 - 144 - } 145 - 146 - 147 - 148 - 149 - void run(MachO& mach, int argc, char** argv, char** envp) { 150 - // I don't understand what it is. 151 - char* apple[2]; 152 - apple[0] = argv[0]; 153 - apple[1] = NULL; 154 - 155 - load(mach); 156 - setupDyldData(mach); 157 - 158 - g_file_map.addWatchDog(last_addr_ + 1); 159 - 160 - char* trampoline_start_addr = 161 - (char*)(((uintptr_t)&trampoline_[0]) & ~0xfff); 162 - uint64_t trampoline_size = 163 - alignMem(&trampoline_[0] + trampoline_.size() - trampoline_start_addr, 164 - 0x1000); 165 - mprotect(trampoline_start_addr, trampoline_size, 166 - PROT_READ | PROT_WRITE | PROT_EXEC); 167 - 168 - g_timer.print(mach.filename().c_str()); 169 - 170 - mach.close(); 171 - 172 - runInitFuncs(argc, argv, envp, apple); 173 - 174 - LOG << "booting from " << (void*)mach.entry() << "..." << endl; 175 - fflush(stdout); 176 - CHECK(argc > 0); 177 - boot(mach.entry(), argc, argv, envp); 178 - /* 179 - int (*fp)(int, char**, char**) = 180 - (int(*)(int, char**, char**))mach.entry(); 181 - int ret = fp(argc, argv, envp); 182 - exit(ret); 183 - */ 184 - } 185 - 186 - private: 187 - void boot(uint64_t entry, int argc, char** argv, char** envp); 188 - 189 - void pushTrampolineCode(unsigned int c) { 190 - while (c) { 191 - trampoline_.push_back(c & 255); 192 - c = c >> 8; 193 - } 194 - } 195 - 196 - void pushTrampolineCode64(unsigned long long c) { 197 - for (int i = 0; i < 8; i++) { 198 - trampoline_.push_back(c & 255); 199 - c = c >> 8; 200 - } 201 - } 202 - 203 - void pushTrampolineCode32(unsigned int c) { 204 - for (int i = 0; i < 4; i++) { 205 - trampoline_.push_back(c & 255); 206 - c = c >> 8; 207 - } 208 - } 209 - 210 - string trampoline_; 211 - intptr last_addr_; 212 - vector<uint64_t> init_funcs_; 213 - Exports exports_; 214 - vector<pair<string, char*> > seen_weak_binds_; 215 - map<string, string> dylib_to_so_; 216 - map<string, string> symbol_to_so_; 217 - set<string> loaded_dylibs_; 218 - }; 219 - 220 - void MachOLoader::boot( 221 - uint64_t entry, int argc, char** argv, char** envp) { 222 - #ifdef __x86_64__ 223 - // 0x08: argc 224 - // 0x10: argv[0] 225 - // 0x18: argv[1] 226 - // ...: argv[n] 227 - // 0 228 - // envp[0] 229 - // envp[1] 230 - // envp[n] 231 - 232 - // TODO: add 'apple'! 233 - 234 - __asm__ volatile(" mov %1, %%rax;\n" 235 - " mov %2, %%rdx;\n" 236 - " push $0;\n" 237 - // TODO(hamaji): envp 238 - " push $0;\n" 239 - ".loop64:\n" 240 - " sub $8, %%rdx;\n" 241 - " push (%%rdx);\n" 242 - " dec %%eax;\n" 243 - " jnz .loop64;\n" 244 - " mov %1, %%eax;\n" 245 - " push %%rax;\n" 246 - " jmp *%0;\n" 247 - ::"r"(entry), "r"(argc), "r"(argv + argc), "r"(envp) 248 - :"%rax", "%rdx"); 249 - //fprintf(stderr, "done!\n"); 250 - #else 251 - __asm__ volatile(" mov %1, %%eax;\n" 252 - " mov %2, %%edx;\n" 253 - " push $0;\n" 254 - ".loop32:\n" 255 - " sub $4, %%edx;\n" 256 - " push (%%edx);\n" 257 - " dec %%eax;\n" 258 - " jnz .loop32;\n" 259 - " mov %1, %%eax;\n" 260 - " push %%eax;\n" 261 - " jmp *%0;\n" 262 - // TODO(hamaji): Fix parameters 263 - ::"r"(entry), "r"(argc), "r"(argv + argc), "g"(envp) 264 - :"%eax", "%edx"); 265 - #endif 266 - } 267 - 268 - void runMachO(MachO& mach, int argc, char** argv, char** envp) { 269 - MachOLoader loader; 270 - g_loader = &loader; 271 - loader.run(mach, argc, argv, envp); 272 - g_loader = NULL; 273 - } 274 - 275 - #if 0 276 - static int getBacktrace(void** trace, int max_depth) { 277 - typedef struct frame { 278 - struct frame *bp; 279 - void *ret; 280 - } frame; 281 - 282 - int depth; 283 - frame* bp = (frame*)__builtin_frame_address(0); 284 - for (depth = 0; bp && depth < max_depth; depth++) { 285 - trace[depth] = bp->ret; 286 - bp = bp->bp; 287 - } 288 - return depth; 289 - } 290 - #endif 291 - 292 - extern "C" { 293 - const char* dumpSymbol(void* p) { 294 - return g_file_map.dumpSymbol(p); 295 - } 296 - } 297 - 298 - /* signal handler for fatal errors */ 299 - static void handleSignal(int signum, siginfo_t* siginfo, void* vuc) { 300 - ucontext_t *uc = (ucontext_t*)vuc; 301 - void* pc = (void*)uc->uc_mcontext.gregs[ 302 - #ifdef __x86_64__ 303 - REG_RIP 304 - #else 305 - REG_EIP 306 - #endif 307 - ]; 308 - 309 - fprintf(stderr, "%s(%d) %d (@%p) PC: %p\n\n", 310 - strsignal(signum), signum, siginfo->si_code, siginfo->si_addr, pc); 311 - 312 - void* trace[100]; 313 - int len = backtrace(trace, 99); 314 - //int len = getBacktrace(trace, 99); 315 - char** syms = backtrace_symbols(trace, len); 316 - for (int i = len - 1; i > 0; i--) { 317 - if (syms[i] && syms[i][0] != '[') { 318 - fprintf(stderr, "%s\n", syms[i]); 319 - } else { 320 - const char* s = dumpSymbol(trace[i]); 321 - if (s) { 322 - fprintf(stderr, "%s\n", s); 323 - } else { 324 - fprintf(stderr, "%p\n", trace[i]); 325 - } 326 - } 327 - } 328 - } 329 - 330 - /* Generate a stack backtrace when a CPU exception occurs. */ 331 - static void initSignalHandler() { 332 - struct sigaction sigact; 333 - sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; 334 - sigact.sa_sigaction = handleSignal; 335 - sigemptyset(&sigact.sa_mask); 336 - sigaction(SIGFPE, &sigact, NULL); 337 - sigaction(SIGILL, &sigact, NULL); 338 - sigaction(SIGSEGV, &sigact, NULL); 339 - sigaction(SIGBUS, &sigact, NULL); 340 - sigaction(SIGABRT, &sigact, NULL); 341 - } 342 - 343 - /* 344 - static bool loadLibMac(const char* mypath) { 345 - if (dlopen("libmac.so", RTLD_LAZY | RTLD_GLOBAL)) { 346 - return true; 347 - } 348 - 349 - char buf[PATH_MAX + 100]; 350 - strcpy(buf, mypath); 351 - char* p = strrchr(buf, '/'); 352 - if (!p) { 353 - fprintf(stderr, "Weird loader path: %s\n", mypath); 354 - exit(1); 355 - } 356 - strcpy(p, "/libmac.so"); 357 - 358 - if (dlopen(buf, RTLD_LAZY | RTLD_GLOBAL)) { 359 - return true; 360 - } 361 - 362 - sprintf(p, "/libmac%d.so", BITS); 363 - if (dlopen(buf, RTLD_LAZY | RTLD_GLOBAL)) { 364 - return true; 365 - } 366 - 367 - return false; 368 - } 369 - */ 370 - 371 - /* 372 - static void initLibMac() { 373 - char mypath[PATH_MAX + 1]; 374 - ssize_t l = readlink("/proc/self/exe", mypath, PATH_MAX); 375 - if (l < 0) { 376 - err(1, "readlink for /proc/self/exe"); 377 - } 378 - mypath[l] = '\0'; 379 - 380 - if (!loadLibMac(mypath)) { 381 - fprintf(stderr, "libmac not found\n"); 382 - exit(1); 383 - } 384 - 385 - int* LIBMAC_LOG = (int*)dlsym(RTLD_DEFAULT, "LIBMAC_LOG"); 386 - if (LIBMAC_LOG) { 387 - *LIBMAC_LOG = FLAGS_LOG; 388 - } 389 - 390 - char* loader_path = (char*)dlsym(RTLD_DEFAULT, "__loader_path"); 391 - if (!loader_path) { 392 - fprintf(stderr, "wrong libmac: __loader_path not found\n"); 393 - exit(1); 394 - } 395 - strcpy(loader_path, mypath); 396 - } 397 - */ 398 - 399 - // TODO: OMG 400 - static string ld_mac_dlerror_buf; 401 - static bool ld_mac_dlerror_is_set; 402 - 403 - // TODO: broken - should support multiple loads and native libs 404 - void* __darwin_dlopen(const char* filename, int flag) { 405 - LOG << "ld_mac_dlopen: " << filename << " " << flag << endl; 406 - 407 - // TODO: should return main executable on filename == NULL 408 - Timer timer; 409 - timer.start(); 410 - 411 - // TODO(hamaji): Handle failures. 412 - auto_ptr<MachO> dylib_mach(loadDylib(filename)); 413 - 414 - MachOLoader* loader = g_loader; 415 - CHECK(loader); 416 - Exports* exports = new Exports(); 417 - loader->load(*dylib_mach, exports); 418 - 419 - timer.print(filename); 420 - 421 - loader->runInitFuncs(-1, NULL, NULL, NULL); 422 - return exports; 423 - } 424 - 425 - // TODO: broken - should decrease the reference count 426 - static int __darwin_dlclose(void* handle) { 427 - LOG << "ld_mac_dlclose" << endl; 428 - 429 - delete (Exports*)handle; 430 - return 0; 431 - } 432 - 433 - static const char* __darwin_dlerror(void) { 434 - LOG << "ld_mac_dlerror" << endl; 435 - 436 - if (!ld_mac_dlerror_is_set) 437 - return NULL; 438 - ld_mac_dlerror_is_set = false; 439 - return ld_mac_dlerror_buf.c_str(); 440 - } 441 - 442 - static void* __darwin_dlsym(void* handle, const char* symbol) { 443 - LOG << "ld_mac_dlsym: " << symbol << endl; 444 - 445 - // TODO: support RTLD_DEFAULT 446 - 447 - Exports* exports = (Exports*)handle; 448 - Exports::const_iterator found = exports->find(string("_") + symbol); 449 - if (found == exports->end()) { 450 - ld_mac_dlerror_is_set = true; 451 - ld_mac_dlerror_buf = string("undefined symbol: ") + symbol; 452 - return NULL; 453 - } 454 - return (void*)found->second.addr; 455 - } 456 - 457 - /* 458 - void initDlfcn() { 459 - #define SET_DLFCN_FUNC(f) \ 460 - do { \ 461 - void** p = (void**)dlsym(RTLD_DEFAULT, "ld_mac_" #f); \ 462 - *p = (void*)&ld_mac_ ## f; \ 463 - } while (0) 464 - 465 - SET_DLFCN_FUNC(dlopen); 466 - SET_DLFCN_FUNC(dlclose); 467 - SET_DLFCN_FUNC(dlerror); 468 - SET_DLFCN_FUNC(dlsym); 469 - } 470 - */
+116 -11
src/dyld/ld.cpp
··· 15 15 #include <sys/types.h> 16 16 #include <sys/stat.h> 17 17 #include <limits.h> 18 + #include <regex.h> 19 + #include <cassert> 18 20 19 21 static Darling::Mutex g_ldMutex; 20 22 static std::map<std::string, LoadedLibrary*> g_ldLibraries; 21 23 static __thread char g_ldError[256] = ""; 24 + static regex_t g_reAutoMappable; 25 + static LoadedLibrary g_dummyLibrary; 22 26 23 27 extern char g_darwin_executable_path[PATH_MAX]; 24 28 ··· 27 31 LIB_PATH, "/usr/lib", "/usr/local/lib" 28 32 }; 29 33 34 + static const char* g_suffixes[] = { "$DARWIN_EXTSN", "$UNIX2003", "$NOCANCEL" }; 35 + 30 36 static void* attemptDlopen(const char* filename, int flag); 31 37 static int translateFlags(int flags); 38 + __attribute__((constructor)) static void initLD(); 32 39 33 40 extern MachOLoader* g_loader; 34 41 extern char g_darwin_executable_path[PATH_MAX]; 42 + extern char g_sysroot[PATH_MAX]; 35 43 extern int g_argc; 36 44 extern char** g_argv; 37 45 extern FileMap g_file_map; 38 46 39 47 #define RET_IF(x) { if (void* p = x) return p; } 40 48 49 + static void initLD() 50 + { 51 + int rv = regcomp(&g_reAutoMappable, "/(lib[[:alnum:]\\-]+)\\.([[:digit:]]+)(\\.[[:digit:]]+)?\\.dylib", REG_EXTENDED); 52 + assert(rv == 0); 53 + 54 + g_dummyLibrary.name = "/dev/null"; 55 + g_dummyLibrary.refCount = 1; 56 + g_dummyLibrary.type = LoadedLibraryDummy; 57 + g_dummyLibrary.nativeRef = 0; 58 + g_dummyLibrary.exports = 0; 59 + } 60 + 41 61 void* __darwin_dlopen(const char* filename, int flag) 42 62 { 43 63 TRACE2(filename, flag); ··· 58 78 start_search: 59 79 if (*filename == '/') 60 80 { 81 + if (g_sysroot[0]) 82 + { 83 + path = g_sysroot + std::string(filename) + ".so"; 84 + LOG << "Trying " << path << std::endl; 85 + if (::access(path.c_str(), R_OK) == 0) 86 + RET_IF( attemptDlopen(path.c_str(), flag) ); 87 + 88 + path = std::string(g_sysroot) + filename; 89 + if (::access(path.c_str(), R_OK) == 0) 90 + RET_IF( attemptDlopen(path.c_str(), flag) ); 91 + } 92 + 61 93 path = std::string(filename) + ".so"; 62 94 LOG << "Trying " << path << std::endl; 63 95 if (::access(path.c_str(), R_OK) == 0) ··· 74 106 if (::access(path.c_str(), R_OK) == 0) 75 107 RET_IF( attemptDlopen(path.c_str(), flag) ); 76 108 109 + regmatch_t matches[3]; 110 + if (regexec(&g_reAutoMappable, filename, 3, matches, 0) == 0) 111 + { 112 + path = std::string(filename, matches[0].rm_so+1); 113 + path += std::string(filename + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so); 114 + path += ".so."; 115 + path += std::string(filename + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so); 116 + 117 + if (::access(path.c_str(), R_OK) == 0) 118 + { 119 + LOG << "Warning: Automatically mapping " << filename << " to " << path << std::endl; 120 + RET_IF( attemptDlopen(path.c_str(), flag) ); 121 + } 122 + 123 + //path = std::string(filename, matches[0].rm_so+1); 124 + path = std::string(filename + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so); 125 + path += ".so."; 126 + path += std::string(filename + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so); 127 + 128 + LOG << path << std::endl; 129 + 130 + //if (::access(path.c_str(), R_OK) == 0) 131 + //{ 132 + LOG << "Warning: Trying to remap " << filename << " to " << path << std::endl; 133 + RET_IF( attemptDlopen(path.c_str(), flag) ); 134 + //} 135 + } 136 + 77 137 if (strcmp(INSTALL_PREFIX, "/usr") != 0) 78 138 { 79 139 // We need to change the prefix in filename if present ··· 123 183 } 124 184 } 125 185 126 - strcpy(g_ldError, "File not found"); 186 + if (!g_ldError[0]) 187 + snprintf(g_ldError, sizeof(g_ldError)-1, "File not found: %s", filename); 127 188 return 0; 128 189 } 129 190 ··· 148 209 static bool isSymlink(const char* path) 149 210 { 150 211 struct stat st; 151 - if (::stat(path, &st) == -1) 212 + if (::lstat(path, &st) == -1) 152 213 return false; 153 214 return S_ISLNK(st.st_mode); 154 215 } ··· 159 220 160 221 TRACE2(filename,flag); 161 222 223 + strcpy(name, filename); 224 + 162 225 // Resolve symlinks so that we don't load the same library multiple times 163 - if (isSymlink(filename) && ::readlink(filename, name, sizeof name) == -1) 226 + if (isSymlink(filename)) 164 227 { 165 - LOG << "Invalid symlink found: " << filename << std::endl; 166 - return 0; 228 + ssize_t len = ::readlink(filename, name, sizeof name); 229 + if (len == -1) 230 + { 231 + LOG << "Invalid symlink found: " << filename << std::endl; 232 + return 0; 233 + } 234 + else 235 + name[len] = 0; 167 236 } 168 - else 169 - strcpy(name, filename); 237 + 238 + if (strcmp(name, "/dev/null") == 0) 239 + { 240 + // We return a dummy 241 + return &g_dummyLibrary; 242 + } 170 243 171 244 std::map<std::string,LoadedLibrary*>::iterator it = g_ldLibraries.find(name); 172 245 if (it != g_ldLibraries.end()) ··· 191 264 LOG << "Loading a native library " << name << std::endl; 192 265 // We're loading a native library 193 266 // TODO: flags 194 - void* d = ::dlopen(name, RTLD_NOW); 267 + void* d = ::dlopen(name, RTLD_NOW|RTLD_GLOBAL); 195 268 if (d != 0) 196 269 { 270 + LOG << "Native library loaded\n"; 271 + 197 272 LoadedLibrary* lib = new LoadedLibrary; 198 273 lib->name = name; 199 274 lib->refCount = 1; ··· 206 281 } 207 282 else 208 283 { 209 - LOG << "Library failed to load: " << ::dlerror() << std::endl; 210 - strcpy(g_ldError, ::dlerror()); 284 + LOG << "Native library failed to load\n"; 285 + 286 + const char* err; 287 + if ((err = ::dlerror()) && !g_ldError[0]) // we don't overwrite previous errors 288 + { 289 + LOG << "Library failed to load: " << err << std::endl; 290 + strcpy(g_ldError, err); 291 + } 211 292 return 0; 212 293 } 213 294 } 214 295 else 215 296 { 297 + LOG << "Loading a Mach-O library\n"; 216 298 // We're loading a Mach-O library 217 299 try 218 300 { ··· 299 381 return g_ldError[0] ? g_ldError : 0; 300 382 } 301 383 384 + static const char* translateSymbol(const char* symbol) 385 + { 386 + std::string s = symbol; 387 + static char symbuffer[255]; 388 + 389 + for (int i = 0; i < sizeof(g_suffixes) / sizeof(g_suffixes[0]); i++) 390 + { 391 + size_t pos = s.find(g_suffixes[i]); 392 + if (pos != std::string::npos) 393 + s.erase(pos, strlen(g_suffixes[i])); 394 + } 395 + 396 + strcpy(symbuffer, s.c_str()); 397 + return symbuffer; 398 + } 399 + 302 400 void* __darwin_dlsym(void* handle, const char* symbol) 303 401 { 304 402 TRACE2(handle, symbol); 305 403 306 404 Darling::MutexLock l(g_ldMutex); 307 405 g_ldError[0] = 0; 406 + 407 + symbol = translateSymbol(symbol); 308 408 309 409 if (handle == DARWIN_RTLD_NEXT || handle == DARWIN_RTLD_SELF || handle == DARWIN_RTLD_MAIN_ONLY || !handle) 310 410 { ··· 317 417 { 318 418 // First try native with the __darwin prefix 319 419 void* sym; 320 - char* buf = reinterpret_cast<char*>(malloc(strlen(symbol+20))); 420 + char* buf = reinterpret_cast<char*>(malloc(strlen(symbol)+20)); 321 421 strcpy(buf, "__darwin_"); 322 422 strcat(buf, symbol); 323 423 ··· 357 457 if (!rv) 358 458 strcpy(g_ldError, ::dlerror()); 359 459 return rv; 460 + } 461 + else if (lib->type == LoadedLibraryDummy) 462 + { 463 + snprintf(g_ldError, sizeof(g_ldError)-1, "Cannot find symbol '%s'", symbol); 464 + return 0; 360 465 } 361 466 else if (!lib->exports) 362 467 {
+1 -1
src/dyld/ld.h
··· 28 28 29 29 } 30 30 31 - enum LoadedLibraryType { LoadedLibraryDylib, LoadedLibraryNative }; 31 + enum LoadedLibraryType { LoadedLibraryDylib, LoadedLibraryNative, LoadedLibraryDummy }; 32 32 33 33 typedef std::unordered_map<std::string, MachO::Export> Exports; 34 34
-155
src/dyld/rename.tab
··· 1 - // Copyright 2011 Shinichiro Hamaji. All rights reserved. 2 - // 3 - // Redistribution and use in source and binary forms, with or without 4 - // modification, are permitted provided that the following conditions 5 - // are met: 6 - // 7 - // 1. Redistributions of source code must retain the above copyright 8 - // notice, this list of conditions and the following disclaimer. 9 - // 10 - // 2. Redistributions in binary form must reproduce the above 11 - // copyright notice, this list of conditions and the following 12 - // disclaimer in the documentation and/or other materials 13 - // provided with the distribution. 14 - // 15 - // THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY 16 - // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 - // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 - // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR 19 - // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 - // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 - // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 - // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 - // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 - // SUCH DAMAGE. 27 - 28 - // A translation table from Mac symbols to Linux's. 29 - 30 - RENAME(__stderrp, __darwin_stderr) 31 - RENAME(__stdoutp, __darwin_stdout) 32 - RENAME(__stdinp, __darwin_stdin) 33 - WRAP(stderr) 34 - WRAP(stdout) 35 - WRAP(stdin) 36 - 37 - WRAP(fopen) 38 - WRAP(fdopen) 39 - WRAP(freopen) 40 - WRAP(fclose) 41 - WRAP(fread) 42 - WRAP(fwrite) 43 - WRAP(fseek) 44 - WRAP(ftell) 45 - WRAP(rewind) 46 - WRAP(getc) 47 - WRAP(fgetc) 48 - WRAP(ungetc) 49 - WRAP(fgets) 50 - WRAP(putc) 51 - WRAP(fputc) 52 - WRAP(fputs) 53 - WRAP(fscanf) 54 - WRAP(vfscanf) 55 - WRAP(fprintf) 56 - WRAP(vfprintf) 57 - WRAP(fflush) 58 - WRAP(setbuf) 59 - WRAP(setbuffer) 60 - WRAP(ferror) 61 - RENAME(_ferror, __darwin_ferror) 62 - WRAP(fileno) 63 - WRAP(tmpfile) 64 - 65 - RENAME(__srget, __darwin_fgetc) 66 - RENAME(__swbuf, __darwin_fputc) 67 - 68 - RENAME(__toupper, toupper) 69 - RENAME(__tolower, tolower) 70 - 71 - RENAME(opendir$INODE64, opendir) 72 - RENAME(readdir$INODE64, __darwin_readdir64) 73 - WRAP(readdir) 74 - 75 - WRAP(stat) 76 - WRAP(fstat) 77 - WRAP(lstat) 78 - RENAME(stat$INODE64, __darwin_stat64) 79 - RENAME(fstat$INODE64, __darwin_fstat64) 80 - RENAME(lstat$INODE64, __darwin_lstat64) 81 - 82 - WRAP(open) 83 - 84 - WRAP(mmap) 85 - WRAP(sysctl) 86 - 87 - RENAME(realpath$DARWIN_EXTSN, realpath) 88 - 89 - WRAP(execv) 90 - WRAP(execvp) 91 - WRAP(execl) 92 - WRAP(execlp) 93 - WRAP(execve) 94 - WRAP(execle) 95 - WRAP(posix_spawn) 96 - WRAP(posix_spawnp) 97 - 98 - WRAP(posix_spawn_file_actions_init) 99 - WRAP(posix_spawn_file_actions_destroy) 100 - WRAP(posix_spawn_file_actions_addopen) 101 - WRAP(posix_spawn_file_actions_addclose) 102 - WRAP(posix_spawn_file_actions_adddup2) 103 - 104 - RENAME(CC_MD5_Init, MD5_Init) 105 - RENAME(CC_MD5_Update, MD5_Update) 106 - RENAME(CC_MD5_Final, MD5_Final) 107 - RENAME(CC_MD5, MD5) 108 - 109 - WRAP(__cxa_throw) 110 - 111 - RENAME(atexit, __cxa_atexit) 112 - 113 - WRAP(signal) 114 - WRAP(sigaction) 115 - WRAP(sigaltstack) 116 - 117 - #ifdef __x86_64__ 118 - RENAME(__ashldi3, __ashlti3) 119 - RENAME(__ashrdi3, __ashrti3) 120 - RENAME(__cmpdi2, __cmpti2) 121 - RENAME(__divdi3, __divti3) 122 - RENAME(__fixdfdi, __fixdfti) 123 - RENAME(__fixsfdi, __fixsfti) 124 - RENAME(__floatdidf, __floattidf) 125 - RENAME(__floatdisf, __floattisf) 126 - RENAME(__lshrdi3, __lshrti3) 127 - RENAME(__moddi3, __modti3) 128 - RENAME(__udivdi3, __udivti3) 129 - RENAME(__umoddi3, __umodti3) 130 - #endif 131 - 132 - // TODO(hamaji): *attr_gettype and *attr_getpshared 133 - WRAP(pthread_mutexattr_settype) 134 - WRAP(pthread_mutexattr_setpshared) 135 - WRAP(pthread_rwlockattr_setpshared) 136 - 137 - WRAP(dlopen) 138 - WRAP(dlclose) 139 - WRAP(dlerror) 140 - WRAP(dlsym) 141 - // TODO(hamaji): dladdr? 142 - 143 - RENAME(_ZNSt12__basic_fileIcE8sys_openEP7__sFILESt13_Ios_Openmode, 144 - _ZNSt12__basic_fileIcE8sys_openEP8_IO_FILESt13_Ios_Openmode) 145 - 146 - WRAP(uname) 147 - 148 - // TODO(hamaji): Not sure if this is right... 149 - RENAME(select$1050, select) 150 - 151 - WRAP(qsort_r) 152 - 153 - WRAP(newlocale) 154 - 155 - WRAP(compat_mode)
+5 -3
src/libSystem/CMakeLists.txt
··· 51 51 libc/stdio.cpp 52 52 libc/fopsmisc.cpp 53 53 libc/aio.cpp 54 + libc/mount.cpp 54 55 common/path.cpp 55 56 ) 56 57 ··· 60 61 kernel-bsd/io.cpp 61 62 kernel-bsd/wait.cpp 62 63 kernel-bsd/sockets.cpp 64 + kernel-bsd/fs.cpp 63 65 ) 64 66 65 67 set(machkern_SRCS ··· 71 73 kernel-mach/vm.cpp 72 74 ) 73 75 74 - add_library(System.dylib SHARED ${libc_SRCS} ${bsdkern_SRCS} ${machkern_SRCS}) 76 + add_library(System.B.dylib SHARED ${libc_SRCS} ${bsdkern_SRCS} ${machkern_SRCS}) 75 77 # -luuid to make uuid_ functions available for Darwin apps 76 - target_link_libraries(System.dylib -ldl -lpthread -luuid -lmach-o -l:libobjc.so.4 -lrt -lssl) 78 + target_link_libraries(System.B.dylib -ldl -lpthread -luuid -lmach-o -l:libobjc.so.4 -lrt -lssl) 77 79 78 - install(TARGETS System.dylib DESTINATION lib) 80 + install(TARGETS System.B.dylib DESTINATION lib) 79 81
+161
src/libSystem/kernel-bsd/fs.cpp
··· 1 + #include "config.h" 2 + #include "fs.h" 3 + #include <cstring> 4 + #include "common/path.h" 5 + #include "libc/errno.h" 6 + #include "libc/darwin_errno_codes.h" 7 + #include <mntent.h> 8 + #include <limits.h> 9 + #include <sys/types.h> 10 + #include <sys/vfs.h> 11 + #include <sys/statvfs.h> 12 + #include <unistd.h> 13 + #include "log.h" 14 + 15 + template<typename Out> void StatfsLinuxToDarwinGen(const char* path, const struct statvfs* in, Out* out) 16 + { 17 + out->f_bsize = in->f_bsize; 18 + out->f_blocks = out->f_iosize = in->f_blocks; 19 + out->f_bfree = in->f_bfree; 20 + out->f_bavail = in->f_bavail; 21 + out->f_files = in->f_files; 22 + out->f_ffree = in->f_ffree; 23 + out->f_fsid.val[0] = in->f_fsid; 24 + 25 + if (in->f_flag & ST_RDONLY) 26 + out->f_flags |= DARWIN_MNT_RDONLY; 27 + if (in->f_flag & ST_NOSUID) 28 + out->f_flags |= DARWIN_MNT_NOSUID; 29 + 30 + struct mntent* ent = findMountForPath(path); 31 + if (ent) 32 + { 33 + strncpy(out->f_mntfromname, ent->mnt_fsname, sizeof(out->f_mntfromname)-1); // we assume zeroed out, no need to set the last char to NUL 34 + strncpy(out->f_mntonname, ent->mnt_dir, sizeof(out->f_mntonname)-1); 35 + strncpy(out->f_fstypename, ent->mnt_fsname, sizeof(out->f_fstypename)-1); 36 + } 37 + } 38 + 39 + template<typename T> int __darwin_statfsGen(const char* path, T* buf) 40 + { 41 + struct statvfs st; 42 + int rv; 43 + 44 + ::memset(buf, 0, sizeof(*buf)); 45 + 46 + rv = statvfs(path, &st); 47 + if (rv == -1) 48 + errnoOut(); 49 + else 50 + StatfsLinuxToDarwinGen(path, &st, buf); 51 + 52 + return rv; 53 + } 54 + 55 + int __darwin_statfs(const char* path, struct __darwin_statfs* buf) 56 + { 57 + return __darwin_statfsGen(translatePathCI(path), buf); 58 + } 59 + 60 + int __darwin_statfs64(const char* path, struct __darwin_statfs64* buf) 61 + { 62 + return __darwin_statfsGen(translatePathCI(path), buf); 63 + } 64 + 65 + template <typename T> int __darwin_fstatfsGen(int fd, T* out) 66 + { 67 + char buf[PATH_MAX], buf2[PATH_MAX]; 68 + sprintf(buf, "/proc/%d/fd/%d", getpid(), fd); 69 + 70 + memset(out, 0, sizeof(*out)); 71 + 72 + if (::readlink(buf, buf2, sizeof buf2) == -1) 73 + { 74 + errnoOut(); 75 + return -1; 76 + } 77 + 78 + return __darwin_statfsGen(buf2, out); 79 + } 80 + 81 + int __darwin_fstatfs(int fd, struct __darwin_statfs* buf) 82 + { 83 + return __darwin_fstatfsGen(fd, buf); 84 + } 85 + 86 + int __darwin_fstatfs64(int fd, struct __darwin_statfs64* buf) 87 + { 88 + return __darwin_fstatfsGen(fd, buf); 89 + } 90 + 91 + template<typename Stat> int __darwin_getfsstatGen(Stat* buf, int bufsize, int flags) 92 + { 93 + FILE* f = setmntent("/proc/mounts", "r"); 94 + struct mntent *ent; 95 + 96 + if (!f) 97 + { 98 + LOG << "Cannot access /proc/mounts!\n"; 99 + errno = DARWIN_ENOENT; 100 + return -1; 101 + } 102 + 103 + int count = 0; 104 + while ( (ent = getmntent(f)) != 0 && ((count+1)*sizeof(*buf) < bufsize || !buf) ) 105 + { 106 + if (buf) 107 + { 108 + int rv = __darwin_statfsGen(ent->mnt_dir, buf+count); 109 + if (rv == -1) 110 + break; 111 + } 112 + count++; 113 + } 114 + 115 + endmntent(f); 116 + return count; 117 + } 118 + 119 + int __darwin_getfsstat(struct __darwin_statfs* buf, int bufsize, int flags) 120 + { 121 + return __darwin_getfsstatGen(buf, bufsize, flags); 122 + } 123 + 124 + int __darwin_getfsstat64(struct __darwin_statfs* buf, int bufsize, int flags) 125 + { 126 + return __darwin_getfsstatGen(buf, bufsize, flags); 127 + } 128 + 129 + void StatfsLinuxToDarwin(const char* path, const struct statvfs* in, struct __darwin_statfs* out) 130 + { 131 + StatfsLinuxToDarwinGen(path, in, out); 132 + } 133 + 134 + void StatfsLinuxToDarwin(const char* path, const struct statvfs* in, struct __darwin_statfs64* out) 135 + { 136 + StatfsLinuxToDarwinGen(path, in, out); 137 + } 138 + 139 + struct mntent* findMountForPath(const char* path) 140 + { 141 + FILE* f = setmntent("/proc/mounts", "r"); 142 + struct mntent *ent, *rv = 0; 143 + 144 + if (!f) 145 + { 146 + LOG << "Cannot access /proc/mounts!\n"; 147 + return 0; 148 + } 149 + 150 + while ((ent = getmntent(f))) 151 + { 152 + if (strncmp(ent->mnt_dir, path, strlen(ent->mnt_dir)) == 0) 153 + { 154 + rv = ent; 155 + break; 156 + } 157 + } 158 + 159 + endmntent(f); 160 + return rv; 161 + }
+86
src/libSystem/kernel-bsd/fs.h
··· 1 + #ifndef BSD_FS_H 2 + #define BSD_FS_H 3 + #include <stdint.h> 4 + #include "common/path.h" 5 + 6 + #define MFSNAMELEN 15 7 + #define MFSTYPENAMELEN 16 8 + #define MNAMELEN 90 9 + 10 + #define DARWIN_MNT_RDONLY 0x1 11 + #define DARWIN_MNT_SYNCHRONOUS 0x2 12 + #define DARWIN_MNT_NOEXEC 0x4 13 + #define DARWIN_MNT_NOSUID 0x8 14 + #define DARWIN_MNT_NODEV 0x10 15 + #define DARWIN_MNT_UNION 0x20 16 + #define DARWIN_MNT_ASYNC 0x40 17 + #define DARWIN_MNT_CPROTECT 0x80 18 + 19 + 20 + typedef struct { int32_t val[2]; } darwin_fsid_t; 21 + 22 + struct __darwin_statfs64 23 + { 24 + uint32_t f_bsize; 25 + int32_t f_iosize; 26 + uint64_t f_blocks; 27 + uint64_t f_bfree; 28 + uint64_t f_bavail; 29 + uint64_t f_files; 30 + uint64_t f_ffree; 31 + darwin_fsid_t f_fsid; 32 + uint32_t f_owner; 33 + uint32_t f_type; 34 + uint32_t f_flags; 35 + uint32_t f_fssubtype; 36 + char f_fstypename[MFSTYPENAMELEN]; 37 + char f_mntonname[DARWIN_MAXPATHLEN]; 38 + char f_mntfromname[DARWIN_MAXPATHLEN]; 39 + uint32_t f_reserved[8]; 40 + }; 41 + 42 + struct __darwin_statfs 43 + { 44 + short f_otype; 45 + short f_oflags; 46 + long f_bsize; 47 + long f_iosize; 48 + long f_blocks; 49 + long f_bfree; 50 + long f_bavail; 51 + long f_files; 52 + long f_ffree; 53 + darwin_fsid_t f_fsid; 54 + uint32_t f_owner; 55 + short f_reserved1; 56 + short f_type; 57 + long f_flags; 58 + long f_reserved2[2]; 59 + char f_fstypename[MFSNAMELEN]; 60 + char f_mntonname[MNAMELEN]; 61 + char f_mntfromname[MNAMELEN]; 62 + char f_reserved3; 63 + long f_reserved4[4]; 64 + }; 65 + 66 + 67 + extern "C" 68 + { 69 + 70 + int __darwin_statfs(const char* path, struct __darwin_statfs* buf); 71 + int __darwin_statfs64(const char* path, struct __darwin_statfs64* buf) asm("__darwin_statfs$INODE64"); 72 + int __darwin_fstatfs(int fd, struct __darwin_statfs* buf); 73 + int __darwin_fstatfs64(int fd, struct __darwin_statfs64* buf) asm("__darwin_fstatfs$INODE64"); 74 + int __darwin_getfsstat(struct __darwin_statfs* buf, int bufsize, int flags); 75 + int __darwin_getfsstat64(struct __darwin_statfs64* buf, int bufsize, int flags) asm("__darwin_getfsstat$INODE64"); 76 + 77 + } 78 + 79 + // out assumed to have been zeroed out 80 + void StatfsLinuxToDarwin(const char* path, const struct statvfs* in, struct __darwin_statfs* out); 81 + void StatfsLinuxToDarwin(const char* path, const struct statvfs* in, struct __darwin_statfs64* out); 82 + 83 + struct mntent; 84 + struct mntent* findMountForPath(const char* path); 85 + 86 + #endif
+1
src/libSystem/kernel-bsd/wait.cpp
··· 1 + #include "config.h" 1 2 #include "wait.h" 2 3 #include "libc/errno.h" 3 4 #include "libc/darwin_errno_codes.h"
+65
src/libSystem/libc/directmap.asm
··· 120 120 __darwin_opendir$INODE64: 121 121 jmp __darwin_opendir WRT ..plt 122 122 123 + global __darwin_rewinddir$INODE64 124 + extern __darwin_rewinddir 125 + __darwin_rewinddir$INODE64: 126 + jmp __darwin_rewinddir WRT ..plt 127 + 123 128 global __darwin_telldir$INODE64 124 129 extern telldir 125 130 __darwin_telldir$INODE64: 126 131 jmp telldir WRT ..plt 127 132 133 + global __darwin_curl_mfprintf 134 + extern __darwin_fprintf 135 + __darwin_curl_mfprintf: 136 + jmp __darwin_fprintf WRT ..plt 137 + 138 + global __darwin_curl_mvfprintf 139 + extern __darwin_vfprintf 140 + __darwin_curl_mvfprintf: 141 + jmp __darwin_vfprintf WRT ..plt 142 + 143 + global realpath$DARWIN_EXTSN 144 + extern __darwin_realpath 145 + realpath$DARWIN_EXTSN: 146 + jmp __darwin_realpath WRT ..plt 147 + 148 + global libintl_gettext 149 + extern gettext 150 + libintl_gettext: 151 + jmp gettext WRT ..plt 152 + 153 + global libintl_dgettext 154 + extern dgettext 155 + libintl_dgettext: 156 + jmp dgettext WRT ..plt 157 + 158 + global libintl_ngettext 159 + extern ngettext 160 + libintl_ngettext: 161 + jmp ngettext WRT ..plt 162 + 163 + global libintl_dngettext 164 + extern dngettext 165 + libintl_dngettext: 166 + jmp dngettext WRT ..plt 167 + 168 + global libintl_dcngettext 169 + extern dcngettext 170 + libintl_dcngettext: 171 + jmp dcngettext WRT ..plt 172 + 173 + global libintl_textdomain 174 + extern textdomain 175 + libintl_textdomain: 176 + jmp textdomain WRT ..plt 177 + 178 + global libintl_bindtextdomain 179 + extern bindtextdomain 180 + libintl_bindtextdomain: 181 + jmp bindtextdomain WRT ..plt 182 + 183 + global libintl_bind_textdomain 184 + extern bind_textdomain_codeset 185 + libintl_bind_textdomain: 186 + jmp bind_textdomain_codeset WRT ..plt 187 + 188 + global libintl_setlocale 189 + extern setlocale 190 + libintl_setlocale: 191 + jmp setlocale WRT ..plt 192 +
+18
src/libSystem/libc/directmap.lst
··· 24 24 25 25 ;;; dir.cpp 26 26 __darwin_opendir$INODE64;__darwin_opendir 27 + __darwin_rewinddir$INODE64;__darwin_rewinddir 27 28 __darwin_telldir$INODE64;telldir 29 + 30 + __darwin_curl_mfprintf;__darwin_fprintf 31 + __darwin_curl_mvfprintf;__darwin_vfprintf 32 + 33 + realpath$DARWIN_EXTSN;__darwin_realpath 34 + 35 + libintl_gettext;gettext 36 + libintl_dgettext;dgettext 37 + libintl_ngettext;ngettext 38 + libintl_dngettext;dngettext 39 + libintl_dcngettext;dcngettext 40 + libintl_textdomain;textdomain 41 + libintl_bindtextdomain;bindtextdomain 42 + libintl_bind_textdomain;bind_textdomain_codeset 43 + libintl_setlocale;setlocale 44 + 45 +
+3
src/libSystem/libc/fopsmisc.cpp
··· 17 17 18 18 path = translatePathCI(path); 19 19 20 + if (!resolved_path) // DARWIN_EXTSN 21 + resolved_path = static_cast<char*>(malloc(DARWIN_MAXPATHLEN)); 22 + 20 23 char* rv = realpath(path, resolved_path); 21 24 if (!rv) 22 25 errnoOut();
+52
src/libSystem/libc/mount.cpp
··· 1 + #include "mount.h" 2 + #include <mntent.h> 3 + #include "libc/darwin_errno_codes.h" 4 + #include <errno.h> 5 + 6 + template<typename Statfs, typename Fsstatfun> int __darwin_getmntinfoGen(Fsstatfun f, Statfs** mntbufp, int flags) 7 + { 8 + static __thread Statfs* lastMntbufp = 0; 9 + 10 + *mntbufp = 0; 11 + 12 + if (lastMntbufp) 13 + { 14 + delete [] lastMntbufp; 15 + lastMntbufp = 0; 16 + } 17 + 18 + int count = f(0, 0, 0); 19 + 20 + if (count < 0) 21 + return -1; 22 + 23 + lastMntbufp = new Statfs[count]; 24 + if (!lastMntbufp) 25 + { 26 + errno = DARWIN_ENOMEM; 27 + return -1; 28 + } 29 + 30 + count = f(lastMntbufp, count*sizeof(Statfs), 0); 31 + 32 + if (count < 0) 33 + { 34 + delete [] lastMntbufp; 35 + lastMntbufp = 0; 36 + return -1; 37 + } 38 + 39 + *mntbufp = lastMntbufp; 40 + return count; 41 + } 42 + 43 + int __darwin_getmntinfo(struct __darwin_statfs** mntbufp, int flags) 44 + { 45 + return __darwin_getmntinfoGen(__darwin_getfsstat, mntbufp, flags); 46 + } 47 + 48 + int __darwin_getmntinfo64(struct __darwin_statfs64** mntbufp, int flags) 49 + { 50 + return __darwin_getmntinfoGen(__darwin_getfsstat64, mntbufp, flags); 51 + } 52 +
+13
src/libSystem/libc/mount.h
··· 1 + #ifndef LIBC_MOUNT_H 2 + #define LIBC_MOUNT_H 3 + #include "kernel-bsd/fs.h" 4 + 5 + extern "C" 6 + { 7 + 8 + int __darwin_getmntinfo(struct __darwin_statfs** mntbufp, int flags); 9 + int __darwin_getmntinfo64(struct __darwin_statfs64** mntbufp, int flags) asm("__darwin_getmntinfo$INODE64"); 10 + 11 + } 12 + 13 + #endif
+38 -6
src/libSystem/libc/stdio.cpp
··· 1 + #include "config.h" 1 2 #include "stdio.h" 2 3 #include "errno.h" 3 4 #include "common/path.h" ··· 7 8 #include <cstdlib> 8 9 #include <errno.h> 9 10 #include <stdio_ext.h> 11 + #include <cstring> 12 + #include <string> 13 + #include <sys/types.h> 14 + #include <sys/stat.h> 15 + #include <fcntl.h> 10 16 #include "log.h" 11 17 12 - extern "C" __darwin_FILE* __stdinp = 0; 13 - extern "C" __darwin_FILE* __stdoutp = 0; 14 - extern "C" __darwin_FILE* __stderrp = 0; 18 + //extern "C" 19 + //{ 20 + __darwin_FILE* __stdinp asm("__stdinp") = 0; 21 + __darwin_FILE* __stdoutp asm("__stdoutp") = 0; 22 + __darwin_FILE* __stderrp asm("__stderrp") = 0; 23 + //} 15 24 16 25 static __darwin_FILE* InitDarwinFILE(FILE* linux_fp) 17 26 { ··· 39 48 40 49 __darwin_FILE* __darwin_fopen(const char* path, const char* mode) 41 50 { 42 - return InitDarwinFILE(fopen(translatePathCI(path), mode)); 51 + path = translatePathCI(path); 52 + 53 + if (!strchr(mode, 'x')) 54 + return InitDarwinFILE(fopen(path, mode)); 55 + else // DARWIN_EXTSN 56 + { 57 + std::string m = mode; 58 + size_t pos = m.find('x'); 59 + m.erase(pos, 1); 60 + 61 + int flags = O_CREAT | O_EXCL; 62 + if (m.find('a') != std::string::npos) 63 + flags |= O_APPEND; 64 + if (m.find('+') != std::string::npos) 65 + flags |= O_RDWR; 66 + else 67 + flags |= O_WRONLY; 68 + 69 + int fd = ::open(path, flags, 0666); 70 + if (fd == -1) 71 + return 0; 72 + else 73 + return __darwin_fdopen(fd, m.c_str()); 74 + } 43 75 } 44 76 45 77 __darwin_FILE* __darwin_fdopen(int fd, const char* mode) ··· 296 328 297 329 __attribute__((constructor)) static void initStdio() 298 330 { 299 - __stderrp = InitDarwinFILE(stdin); 331 + __stderrp = InitDarwinFILE(stderr); 300 332 __stdoutp = InitDarwinFILE(stdout); 301 - __stdinp = InitDarwinFILE(stderr); 333 + __stdinp = InitDarwinFILE(stdin); 302 334 } 303 335 304 336 int __darwin_remove(const char* path)
+12
src/libSystem/libc/string.cpp
··· 1 1 #include "string.h" 2 2 #include <cstdlib> 3 + #include <ctype.h> 3 4 4 5 size_t strlcpy(char* dst, const char* src, size_t size) 5 6 { ··· 40 41 { 41 42 return MB_CUR_MAX; 42 43 } 44 + 45 + int __toupper(int c) 46 + { 47 + return toupper(c); 48 + } 49 + 50 + int __tolower(int c) 51 + { 52 + return tolower(c); 53 + } 54 +
+3
src/libSystem/libc/string.h
··· 12 12 void memset_pattern16(char* b, const char* pattern4, size_t len); 13 13 14 14 int __mb_cur_max(); 15 + int __toupper(int c); 16 + int __tolower(int c); 17 + 15 18 16 19 } 17 20
+12 -6
src/libmach-o/MachOImpl.cpp
··· 37 37 #include <cstdio> 38 38 #include <cstdlib> 39 39 #include <cstring> 40 + #include <stdexcept> 40 41 41 42 #define N_WEAK_DEF 0x0080 42 43 #define FLAGS_READ_SYMTAB 1 ··· 235 236 m_fd = fd; 236 237 m_offset = offset; 237 238 m_text_offset = 0; 238 - m_main = 0; 239 + m_main = m_entry = 0; 239 240 240 241 if (!m_mapped_size) 241 242 m_mapped_size = ::lseek(m_fd, 0, SEEK_END); ··· 245 246 char* bin = m_mapped = reinterpret_cast<char*>( 246 247 ::mmap(NULL, m_mapped_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, m_fd, offset) 247 248 ); 249 + 250 + if (bin == MAP_FAILED) 251 + throw std::runtime_error("Cannot mmap Mach-O file"); 252 + 248 253 m_base = bin; 249 254 250 255 mach_header* header = reinterpret_cast<mach_header*>(bin); 251 256 252 - LOGF("magic=%x cpu=%d cpusub=%d file=%d ncmds=%d sizecmd=%d flags=%x\n", 253 - header->magic, header->cputype, header->cpusubtype, 254 - header->filetype, header->ncmds, header->sizeofcmds, 255 - header->flags); 256 - 257 257 m_is64 = false; 258 258 if (header->magic == MH_MAGIC_64) 259 259 m_is64 = true; ··· 262 262 fprintf(stderr, "Not mach-o: %s\n", filename); 263 263 exit(1); // TODO: throw instead 264 264 } 265 + 266 + LOGF("magic=%x cpu=%d cpusub=%d file=%d ncmds=%d sizecmd=%d flags=%x\n", 267 + header->magic, header->cputype, header->cpusubtype, 268 + header->filetype, header->ncmds, header->sizeofcmds, 269 + header->flags); 270 + 265 271 m_ptrsize = m_is64 ? 8 : 4; 266 272 267 273 if ((header->cputype & 0x00ffffff) != CPU_TYPE_X86)
+10 -1
src/util/log.cc
··· 27 27 28 28 #include "env_flags.h" 29 29 30 - DEFINE_bool(LOG, false, "Output bunch of logs"); 30 + // DEFINE_bool(LOG, false, "Output bunch of logs"); 31 + extern "C" bool g_loggingEnabled = false; 32 + 33 + __attribute__((constructor)) static void initLogging() 34 + { 35 + const char* v = getenv("DYLD_DEBUG"); 36 + if (v && atoi(v)) 37 + g_loggingEnabled = true; 38 + } 39 +
+6 -1
src/util/log.h
··· 31 31 #include <assert.h> 32 32 #include <stdio.h> 33 33 34 + #ifdef __cplusplus 35 + # include <iostream> 36 + #endif 37 + 34 38 //#include "env_flags.h" 35 39 36 40 //DECLARE_bool(LOG); 37 - #define FLAGS_LOG 1 41 + extern bool g_loggingEnabled; 42 + #define FLAGS_LOG g_loggingEnabled 38 43 39 44 #ifdef NOLOG 40 45 # define LOG if (0) std::cout
+4 -1
src/util/mutex.h
··· 11 11 public: 12 12 Mutex() 13 13 { 14 - pthread_mutex_init(&m_mutex, 0); 14 + pthread_mutexattr_t attr; 15 + pthread_mutexattr_init(&attr); 16 + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 17 + pthread_mutex_init(&m_mutex, &attr); 15 18 } 16 19 ~Mutex() 17 20 {
+10 -12
src/util/trace.cpp
··· 2 2 #include <stdarg.h> 3 3 #include <iostream> 4 4 5 - bool g_enableTrace = false; 6 - 7 5 TraceHelper::TraceHelper(const char* funcName) 8 6 { 9 - std::cerr << "TRACE(): " << funcName << ""; 7 + if (g_loggingEnabled) 8 + std::cerr << "TRACE(): " << funcName << ""; 10 9 } 11 10 TraceHelper::~TraceHelper() 12 11 { 13 - std::cerr << std::endl; 14 - } 15 - 16 - void enableTrace(bool enable) 17 - { 18 - g_enableTrace = enable; 12 + if (g_loggingEnabled) 13 + std::cerr << std::endl; 19 14 } 20 15 21 16 template<> void logPrint<std::string>(std::string value) 22 17 { 23 - std::cerr << '\"' << value << '\"'; 18 + if (g_loggingEnabled) 19 + std::cerr << '\"' << value << '\"'; 24 20 } 25 21 template<> void logPrint<const char*>(const char* value) 26 22 { 27 - std::cerr << '\"' << value << '\"'; 23 + if (g_loggingEnabled) 24 + std::cerr << '\"' << value << '\"'; 28 25 } 29 26 template<> void logPrint<ArgName>(ArgName value) 30 27 { 31 - std::cerr << value.name; 28 + if (g_loggingEnabled) 29 + std::cerr << value.name; 32 30 }
+3 -3
src/util/trace.h
··· 1 1 #ifndef DARLING_TRACE_H 2 2 #define DARLING_TRACE_H 3 3 #include <iostream> 4 + #include "log.h" 4 5 5 - extern bool g_enableTrace; 6 6 void logTrace(const char* funcName, ...); 7 - void enableTrace(bool enable); 8 7 9 8 struct ArgName 10 9 { ··· 14 13 15 14 template<typename T> void logPrint(T value) 16 15 { 17 - std::cerr << value; 16 + if (g_loggingEnabled) 17 + std::cerr << value; 18 18 } 19 19 template<> void logPrint<const char*>(const char* value); 20 20 template<> void logPrint<std::string>(std::string value);