| 1369 | } |
| 1370 | |
| 1371 | bool LinkerScannerMgr::init() |
| 1372 | { |
| 1373 | if (!_pMem || !isValid()) |
| 1374 | return false; |
| 1375 | |
| 1376 | if (_init) |
| 1377 | return true; |
| 1378 | |
| 1379 | for (const auto &sym : dsymbols()) |
| 1380 | { |
| 1381 | if (KittyUtils::String::startsWith(sym.first, "__dl__ZL11solist_head") || |
| 1382 | KittyUtils::String::startsWith(sym.first, "__dl__ZL6solist")) |
| 1383 | { |
| 1384 | _linker_syms.solist = sym.second; |
| 1385 | continue; |
| 1386 | } |
| 1387 | if (KittyUtils::String::startsWith(sym.first, "__dl__ZL6somain")) |
| 1388 | { |
| 1389 | _linker_syms.somain = sym.second; |
| 1390 | continue; |
| 1391 | } |
| 1392 | if (KittyUtils::String::startsWith(sym.first, "__dl__ZL11solist_tail") || |
| 1393 | KittyUtils::String::startsWith(sym.first, "__dl__ZL6sonext")) |
| 1394 | { |
| 1395 | _linker_syms.sonext = sym.second; |
| 1396 | continue; |
| 1397 | } |
| 1398 | if (_linker_syms.solist && _linker_syms.somain && _linker_syms.sonext) |
| 1399 | break; |
| 1400 | } |
| 1401 | |
| 1402 | if (!(_linker_syms.solist && _linker_syms.somain && _linker_syms.sonext)) |
| 1403 | { |
| 1404 | return false; |
| 1405 | } |
| 1406 | |
| 1407 | KITTY_LOGD("solist(%zx) | somain(%zx) | sonext(%zx)", solist(), somain(), sonext()); |
| 1408 | |
| 1409 | std::vector<char> solist_buf(KT_SOINFO_BUFFER_SZ, 0); |
| 1410 | _pMem->Read(solist(), solist_buf.data(), KT_SOINFO_BUFFER_SZ); |
| 1411 | |
| 1412 | std::vector<char> si_buf(KT_SOINFO_BUFFER_SZ, 0); |
| 1413 | uintptr_t somain_ptr = somain(); |
| 1414 | _pMem->Read(somain_ptr ? somain_ptr : sonext(), si_buf.data(), KT_SOINFO_BUFFER_SZ); |
| 1415 | |
| 1416 | auto allMaps = KittyMemoryEx::getAllMaps(_pMem->processID()); |
| 1417 | |
| 1418 | ElfScanner si_elf{}; |
| 1419 | for (size_t i = 0; i < si_buf.size(); i += sizeof(uintptr_t)) |
| 1420 | { |
| 1421 | uintptr_t possible_base = *(uintptr_t *)&si_buf[i]; |
| 1422 | |
| 1423 | auto tmp_map = KittyMemoryEx::getAddressMap(_pMem->processID(), possible_base, allMaps); |
| 1424 | if (!tmp_map.isValid() || !tmp_map.readable || tmp_map.writeable || tmp_map.is_shared) |
| 1425 | continue; |
| 1426 | |
| 1427 | si_elf = ElfScanner(_pMem, possible_base, allMaps); |
| 1428 | if (si_elf.isValid()) |
nothing calls this directly
no test coverage detected