this repo has no description
1
fork

Configure Feed

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

Weak binding fixes (but still not what I'd like to see)

+129 -51
+28 -10
src/dyld/MachOLoader.cpp
··· 49 49 extern int g_argc; 50 50 extern char** g_argv; 51 51 extern bool g_trampoline; 52 + extern bool g_noWeak; 52 53 extern std::set<LoaderHookFunc*> g_machoLoaderHooks; 53 54 extern MachOLoader* g_loader; 54 55 ··· 350 351 351 352 if (bind->is_weak) 352 353 { 354 + if (g_noWeak) 355 + continue; 353 356 if (last_weak_name == name) 354 357 { 355 358 sym = last_weak_sym; ··· 371 374 } 372 375 else 373 376 { 374 - const Exports::const_iterator export_found = m_exports.find(bind->name); 375 - if (export_found != m_exports.end()) 376 - *ptr = last_weak_sym = (uintptr_t)export_found->second.addr; 377 + void* expAddr = __darwin_dlsym(__DARLING_RTLD_STRONG, name.c_str()); 378 + if (expAddr != nullptr) 379 + { 380 + LOG << "Weak reference overridden for " << name << std::endl; 381 + LOG << (void*)*ptr << " -> " << (void*)expAddr << " @" << ptr << std::endl; 382 + *ptr = last_weak_sym = (uintptr_t)expAddr; 383 + } 377 384 else 385 + { 386 + LOG << "Weak reference not overriden for " << name << std::endl; 378 387 last_weak_sym = *ptr; 388 + } 379 389 } 380 390 } 381 391 ··· 474 484 475 485 std::inplace_merge(m_seen_weak_binds.begin(), m_seen_weak_binds.begin() + seen_weak_binds_orig_size, m_seen_weak_binds.end()); 476 486 487 + // This return value is used by dyld_stub_binder 477 488 return reinterpret_cast<void*>(sym); 478 489 } 479 490 ··· 488 499 exp->addr += base; 489 500 // TODO(hamaji): Not 100% sure, but we may need to consider weak symbols. 490 501 if (!exports->insert(make_pair(exp->name, *exp)).second) 491 - fprintf(stderr, "duplicated exported symbol: %s\n", exp->name.c_str()); 502 + { 503 + // Until we support two-level namespaces, duplicate symbols may happen where they would not happen on Darwin. 504 + // In this case we simply use the first known symbol. 505 + LOG << "Warning: duplicate exported symbol name: " << exp->name << std::endl; 506 + } 492 507 } 493 508 } 494 509 ··· 496 511 497 512 void MachOLoader::load(const MachO& mach, std::string sourcePath, Exports* exports, bool bindLater, bool bindLazy) 498 513 { 499 - if (!exports) 500 - exports = &m_exports; 501 - 502 514 intptr slide = 0; 503 515 intptr base = 0; 516 + 517 + m_exports.push_back(exports); 504 518 505 - strncpy(g_darwin_loader_path, sourcePath.c_str(), PATH_MAX-1); 506 - g_darwin_loader_path[PATH_MAX-1] = 0; 519 + if (!g_darwin_loader_path[0]) 520 + { 521 + strncpy(g_darwin_loader_path, sourcePath.c_str(), PATH_MAX-1); 522 + g_darwin_loader_path[PATH_MAX-1] = 0; 523 + } 507 524 508 525 loadSegments(mach, &slide, &base); 509 526 ··· 592 609 // envCopy.push_back(envp[i]); 593 610 envCopy.push_back(0); 594 611 595 - load(mach, g_darwin_executable_path, nullptr, true, bindLazy); 612 + m_mainExports = new Exports; 613 + load(mach, g_darwin_executable_path, m_mainExports, true, bindLazy); 596 614 setupDyldData(mach); 597 615 598 616 g_file_map.addWatchDog(m_last_addr + 1);
+4 -2
src/dyld/MachOLoader.h
··· 86 86 // Starts an application 87 87 void run(MachO& mach, int argc, char** argv, char** envp, bool bindLazy = false); 88 88 89 - const Exports& getExports() const { return m_exports; } 89 + const std::list<Exports*>& getExports() const { return m_exports; } 90 + Exports* getMainExecutableExports() const { return m_mainExports; } 90 91 91 92 private: 92 93 // Jumps to the application entry ··· 97 98 private: 98 99 intptr m_last_addr; 99 100 std::vector<uint64_t> m_init_funcs; 100 - Exports m_exports; 101 + std::list<Exports*> m_exports; 102 + Exports* m_mainExports; 101 103 std::vector<std::pair<std::string, uintptr_t> > m_seen_weak_binds; 102 104 UndefMgr* m_pUndefMgr; 103 105 TrampolineMgr* m_pTrampolineMgr;
+3
src/dyld/dyld.cpp
··· 37 37 char g_loader_path[PATH_MAX]; 38 38 char g_sysroot[PATH_MAX] = ""; 39 39 bool g_trampoline = false; 40 + bool g_noWeak = false; 40 41 41 42 extern "C" char* __loader_path; 42 43 char* __loader_path = g_loader_path; ··· 94 95 mtrace(); 95 96 if (getenv("DYLD_TRAMPOLINE") && atoi(getenv("DYLD_TRAMPOLINE"))) 96 97 g_trampoline = true; 98 + if (getenv("DYLD_NO_WEAK")) 99 + g_noWeak = true; 97 100 98 101 g_mainBinary = MachO::readFile(argv[1], ARCH_NAME); 99 102
+90 -38
src/dyld/ld.cpp
··· 41 41 #include <cassert> 42 42 #include <list> 43 43 #include <algorithm> 44 + #include <execinfo.h> 44 45 45 46 static Darling::Mutex g_ldMutex; 46 47 static std::map<std::string, LoadedLibrary*> g_ldLibraries; ··· 229 230 if (strncmp(filename, "@executable_path", 16) == 0) 230 231 { 231 232 path = replacePathPrefix("@executable_path", filename, g_darwin_executable_path); 232 - std::cout << "Full path: " << path << std::endl; 233 + //std::cout << "Full path: " << path << std::endl; 233 234 if (::access(path.c_str(), R_OK) == 0) 234 235 RET_IF( attemptDlopen(path.c_str(), flag) ); 235 236 } ··· 411 412 bool global = flag & RTLD_GLOBAL && !(flag & RTLD_LOCAL); 412 413 bool lazy = flag & RTLD_LAZY && !(flag & RTLD_NOW); 413 414 414 - if (!global) 415 - { 415 + //if (!global) 416 + //{ 416 417 lib->exports = new Exports; 417 418 g_loader->load(*machO, name, lib->exports, nobind, lazy); 418 - } 419 - else 420 - g_loader->load(*machO, name, 0, nobind, lazy); 419 + //} 420 + //else 421 + // g_loader->load(*machO, name, 0, nobind, lazy); 421 422 422 423 if (!nobind) 423 424 { ··· 519 520 return symbuffer; 520 521 } 521 522 522 - void* __darwin_dlsym(void* handle, const char* symbol) 523 + void* __darwin_dlsym(void* handle, const char* symbol, void* extra) 523 524 { 524 525 TRACE2(handle, symbol); 525 526 526 527 Darling::MutexLock l(g_ldMutex); 527 528 g_ldError[0] = 0; 528 529 529 - if (handle == DARWIN_RTLD_NEXT || handle == DARWIN_RTLD_SELF || handle == DARWIN_RTLD_MAIN_ONLY || !handle) 530 - { 531 - LOG << "Cannot yet handle certain DARWIN_RTLD_* search strategies, falling back to RTLD_DEFAULT\n"; 530 + if (!handle) 532 531 handle = DARWIN_RTLD_DEFAULT; 533 - } 534 532 535 - handling: 536 - if (handle == DARWIN_RTLD_DEFAULT) 533 + //if (handle == DARWIN_RTLD_NEXT || handle == DARWIN_RTLD_SELF || handle == DARWIN_RTLD_MAIN_ONLY || !handle) 534 + //{ 535 + // LOG << "Cannot yet handle certain DARWIN_RTLD_* search strategies, falling back to RTLD_DEFAULT\n"; 536 + // handle = DARWIN_RTLD_DEFAULT; 537 + //} 538 + 539 + //handling: 540 + if (handle == DARWIN_RTLD_DEFAULT || handle == __DARLING_RTLD_STRONG) 537 541 { 538 542 // First try native with the __darwin prefix 539 543 void* sym; ··· 546 550 return sym; 547 551 548 552 // Now try Darwin libraries 549 - const Exports& e = g_loader->getExports(); 550 - Exports::const_iterator itSym = e.find(symbol); 553 + const std::list<Exports*>& le = g_loader->getExports(); 554 + std::list<Exports*>::const_iterator it = le.begin(); 555 + 556 + while (it != le.end()) 557 + { 558 + const Exports* e = *it; 559 + Exports::const_iterator itSym = e->find(symbol); 551 560 552 - if (itSym == e.end()) 553 - itSym = e.find(std::string("_") + symbol); 561 + if (itSym == e->end()) 562 + itSym = e->find(std::string("_") + symbol); // TODO: WTF? 554 563 555 - if (itSym == e.end()) 564 + if (itSym != e->end()) 565 + { 566 + if (handle != __DARLING_RTLD_STRONG || !(itSym->second.flag & 4)) 567 + return reinterpret_cast<void*>(itSym->second.addr); 568 + } 569 + it++; 570 + } 571 + 572 + // Now try without a prefix 573 + const char* translated = translateSymbol(symbol); 574 + LOG << "Trying " << translated << std::endl; 575 + sym = ::dlsym(RTLD_DEFAULT, translated); 576 + if (sym) 577 + return sym; 578 + 579 + // Now we fail 580 + snprintf(g_ldError, sizeof(g_ldError)-1, "Cannot find symbol '%s'", symbol); 581 + return nullptr; 582 + } 583 + else if (handle == DARWIN_RTLD_NEXT) 584 + { 585 + // For this, we'll have to rethink and integrate Exports in MachOLoader and LoadedLibrary in here 586 + abort(); 587 + } 588 + else if (handle == DARWIN_RTLD_MAIN_ONLY || handle == DARWIN_RTLD_SELF) 589 + { 590 + Exports* exports = nullptr; 591 + if (handle == DARWIN_RTLD_MAIN_ONLY) 592 + exports = g_loader->getMainExecutableExports(); 593 + else 556 594 { 557 - // Now try without a prefix 558 - const char* translated = translateSymbol(symbol); 559 - LOG << "Trying " << translated << std::endl; 560 - sym = ::dlsym(RTLD_DEFAULT, translated); 561 - if (sym) 562 - return sym; 563 - 564 - // Now we fail 595 + void* retaddr; 596 + const char* name; 597 + 598 + backtrace(&retaddr, 1); 599 + 600 + name = g_file_map.fileNameForAddr(retaddr); 601 + if (!name) 602 + { 603 + strcpy(g_ldError, "Couldn't determine the current module"); 604 + return nullptr; 605 + } 606 + 607 + auto it = g_ldLibraries.find(name); 608 + if (it == g_ldLibraries.end()) 609 + { 610 + strcpy(g_ldError, "Couldn't determine the current module by path"); 611 + return nullptr; 612 + } 613 + 614 + exports = it->second->exports; 615 + } 616 + 617 + Exports::iterator itSym = exports->find(symbol); 618 + if (itSym == exports->end()) 619 + { 565 620 snprintf(g_ldError, sizeof(g_ldError)-1, "Cannot find symbol '%s'", symbol); 566 621 return 0; 567 622 } ··· 570 625 } 571 626 else 572 627 { 573 - LoadedLibrary* lib = reinterpret_cast<LoadedLibrary*>(handle); 574 - /*if (!lib) 575 - { 576 - strcpy(g_ldError, "Invalid handle passed to __darwin_dlsym()"); 577 - return 0; 578 - }*/ 628 + LoadedLibrary* lib = nullptr; 629 + 630 + lib = reinterpret_cast<LoadedLibrary*>(handle); 579 631 580 632 if (lib->type == LoadedLibraryNative) 581 633 { ··· 589 641 snprintf(g_ldError, sizeof(g_ldError)-1, "Cannot find symbol '%s'", symbol); 590 642 return 0; 591 643 } 592 - else if (!lib->exports) 593 - { 594 - // TODO: this isn't 100% correct 595 - handle = DARWIN_RTLD_DEFAULT; 596 - goto handling; 597 - } 644 + //else if (!lib->exports) 645 + //{ 646 + // // TODO: this isn't 100% correct 647 + // handle = DARWIN_RTLD_DEFAULT; 648 + // goto handling; 649 + //} 598 650 else 599 651 { 600 652 Exports::iterator itSym = lib->exports->find(symbol);
+4 -1
src/dyld/ld.h
··· 37 37 #define DARWIN_RTLD_SELF ((void*)-3) 38 38 #define DARWIN_RTLD_MAIN_ONLY ((void*)-5) 39 39 40 + // Internal, only for weak symbol resolution 41 + #define __DARLING_RTLD_STRONG ((void*)-20) 42 + 40 43 extern "C" 41 44 { 42 45 43 46 void* __darwin_dlopen(const char* filename, int flag); 44 47 int __darwin_dlclose(void* handle); 45 48 const char* __darwin_dlerror(void); 46 - void* __darwin_dlsym(void* handle, const char* symbol); 49 + void* __darwin_dlsym(void* handle, const char* symbol, void* extra = nullptr); 47 50 int __darwin_dladdr(void *addr, Dl_info *info); 48 51 49 52 }