| 851 | } |
| 852 | |
| 853 | UnloadProtection::UnloadProtection(const CodeCache *cc) { |
| 854 | if (OS::isMusl() || isMainExecutable(cc->imageBase(), cc->maxAddress()) || isLoader(cc->imageBase())) { |
| 855 | _lib_handle = NULL; |
| 856 | _valid = true; |
| 857 | return; |
| 858 | } |
| 859 | |
| 860 | // dlopen() can reopen previously loaded libraries even if the underlying file has been deleted |
| 861 | const char* stripped_name = cc->name(); |
| 862 | size_t name_len = strlen(stripped_name); |
| 863 | if (name_len > 10 && strcmp(stripped_name + name_len - 10, " (deleted)") == 0) { |
| 864 | char* buf = (char*) alloca(name_len - 9); |
| 865 | *stpncpy(buf, stripped_name, name_len - 10) = 0; |
| 866 | stripped_name = buf; |
| 867 | } |
| 868 | |
| 869 | // Protect library from unloading while parsing in-memory ELF program headers. |
| 870 | // Also, dlopen() ensures the library is fully loaded. |
| 871 | _lib_handle = dlopen(stripped_name, RTLD_LAZY | RTLD_NOLOAD); |
| 872 | _valid = _lib_handle != NULL && verifyBaseAddress(cc, _lib_handle); |
| 873 | } |
| 874 | |
| 875 | UnloadProtection::~UnloadProtection() { |
| 876 | if (_lib_handle != NULL) { |
nothing calls this directly
no test coverage detected