| 482 | } |
| 483 | |
| 484 | void LoadHostVDSO() { |
| 485 | // Linux gives the VDSO ELF header base in the auxv value AT_SYSINFO_EHDR. |
| 486 | auto VDSOHeader = ::getauxval(AT_SYSINFO_EHDR); |
| 487 | |
| 488 | if (!VDSOHeader) { |
| 489 | // We couldn't load VDSO, fallback to C implementations. Which will still be faster than emulated libc versions. |
| 490 | LogMan::Msg::IFmt("linux-vdso implementation falling back to libc. Consider enabling VDSO in your kernel."); |
| 491 | return; |
| 492 | } |
| 493 | |
| 494 | auto VDSO = VDSOParser(reinterpret_cast<const uint8_t*>(VDSOHeader)); |
| 495 | |
| 496 | auto SymbolPtr = VDSO.FindSymbol("__kernel_time"); |
| 497 | if (!SymbolPtr) { |
| 498 | SymbolPtr = VDSO.FindSymbol("__vdso_time"); |
| 499 | } |
| 500 | if (SymbolPtr) { |
| 501 | VDSOHandlers::TimePtr = reinterpret_cast<VDSOHandlers::TimeType>(SymbolPtr); |
| 502 | x64::Handler_time = x64::VDSO::time; |
| 503 | x32::Handler_time = x32::VDSO::time; |
| 504 | } |
| 505 | |
| 506 | SymbolPtr = VDSO.FindSymbol("__kernel_gettimeofday"); |
| 507 | if (!SymbolPtr) { |
| 508 | SymbolPtr = VDSO.FindSymbol("__vdso_gettimeofday"); |
| 509 | } |
| 510 | |
| 511 | if (SymbolPtr) { |
| 512 | VDSOHandlers::GetTimeOfDayPtr = reinterpret_cast<VDSOHandlers::GetTimeOfDayType>(SymbolPtr); |
| 513 | x64::Handler_gettimeofday = x64::VDSO::gettimeofday; |
| 514 | x32::Handler_gettimeofday = x32::VDSO::gettimeofday; |
| 515 | } |
| 516 | |
| 517 | SymbolPtr = VDSO.FindSymbol("__kernel_clock_gettime"); |
| 518 | if (!SymbolPtr) { |
| 519 | SymbolPtr = VDSO.FindSymbol("__vdso_clock_gettime"); |
| 520 | } |
| 521 | |
| 522 | if (SymbolPtr) { |
| 523 | VDSOHandlers::ClockGetTimePtr = reinterpret_cast<VDSOHandlers::ClockGetTimeType>(SymbolPtr); |
| 524 | x64::Handler_clock_gettime = x64::VDSO::clock_gettime; |
| 525 | x32::Handler_clock_gettime = x32::VDSO::clock_gettime; |
| 526 | x32::Handler_clock_gettime64 = x32::VDSO::clock_gettime64; |
| 527 | } |
| 528 | |
| 529 | SymbolPtr = VDSO.FindSymbol("__kernel_clock_getres"); |
| 530 | if (!SymbolPtr) { |
| 531 | SymbolPtr = VDSO.FindSymbol("__vdso_clock_getres"); |
| 532 | } |
| 533 | |
| 534 | if (SymbolPtr) { |
| 535 | VDSOHandlers::ClockGetResPtr = reinterpret_cast<VDSOHandlers::ClockGetResType>(SymbolPtr); |
| 536 | x64::Handler_clock_getres = x64::VDSO::clock_getres; |
| 537 | x32::Handler_clock_getres = x32::VDSO::clock_getres; |
| 538 | } |
| 539 | |
| 540 | SymbolPtr = VDSO.FindSymbol("__kernel_getcpu"); |
| 541 | if (!SymbolPtr) { |
no test coverage detected