OpenJDK / jdk / hs
changeset 46629:8eeacdc76bf2
8183262: noexecstack check in os::dll_load on Linux is too expensive
Summary: convert ElfFile::specifies_noexecstack() to static method which read file header and check executable stack flag.
Reviewed-by: iklam, stuefe
author | kvn |
---|---|
date | Wed, 05 Jul 2017 11:03:19 -0700 |
parents | d19bf13a5655 |
children | 75aa3e39d02c cef226af6c02 |
files | hotspot/src/os/linux/vm/os_linux.cpp hotspot/src/share/vm/aot/aotLoader.cpp hotspot/src/share/vm/utilities/elfFile.cpp hotspot/src/share/vm/utilities/elfFile.hpp |
diffstat | 4 files changed, 39 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 17:19:37 2017 +0200 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 11:03:19 2017 -0700 @@ -1639,8 +1639,7 @@ // // See Linux man page execstack(8) for more info. if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) { - ElfFile ef(filename); - if (!ef.specifies_noexecstack()) { + if (!ElfFile::specifies_noexecstack(filename)) { if (!is_init_completed()) { os::Linux::_stack_is_executable = true; // This is OK - No Java threads have been created yet, and hence no
--- a/hotspot/src/share/vm/aot/aotLoader.cpp Wed Jul 05 17:19:37 2017 +0200 +++ b/hotspot/src/share/vm/aot/aotLoader.cpp Wed Jul 05 11:03:19 2017 -0700 @@ -29,6 +29,7 @@ #include "oops/method.hpp" #include "prims/jvm.h" #include "runtime/os.hpp" +#include "runtime/timerTrace.hpp" GrowableArray<AOTCodeHeap*>* AOTLoader::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTCodeHeap*> (2, true); GrowableArray<AOTLib*>* AOTLoader::_libraries = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTLib*> (2, true); @@ -112,6 +113,8 @@ }; void AOTLoader::initialize() { + TraceTime timer("AOT initialization", TRACETIME_LOG(Info, aot, startuptime)); + if (FLAG_IS_DEFAULT(UseAOT) && AOTLibrary != NULL) { // Don't need to set UseAOT on command line when AOTLibrary is specified FLAG_SET_DEFAULT(UseAOT, true);
--- a/hotspot/src/share/vm/utilities/elfFile.cpp Wed Jul 05 17:19:37 2017 +0200 +++ b/hotspot/src/share/vm/utilities/elfFile.cpp Wed Jul 05 11:03:19 2017 -0700 @@ -242,32 +242,45 @@ } #ifdef LINUX -bool ElfFile::specifies_noexecstack() { - Elf_Phdr phdr; - if (!m_file) return true; +bool ElfFile::specifies_noexecstack(const char* filepath) { + // Returns true if the elf file is marked NOT to require an executable stack, + // or if the file could not be opened. + // Returns false if the elf file requires an executable stack, the stack flag + // is not set at all, or if the file can not be read. + if (filepath == NULL) return true; - if (!fseek(m_file, m_elfHdr.e_phoff, SEEK_SET)) { - for (int index = 0; index < m_elfHdr.e_phnum; index ++) { - if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, m_file) != 1) { - m_status = NullDecoder::file_invalid; - return false; + FILE* file = fopen(filepath, "r"); + if (file == NULL) return true; + + // AARCH64 defaults to noexecstack. All others default to execstack. +#ifdef AARCH64 + bool result = true; +#else + bool result = false; +#endif + + // Read file header + Elf_Ehdr head; + if (fread(&head, sizeof(Elf_Ehdr), 1, file) == 1 && + is_elf_file(head) && + fseek(file, head.e_phoff, SEEK_SET) == 0) { + + // Read program header table + Elf_Phdr phdr; + for (int index = 0; index < head.e_phnum; index ++) { + if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, file) != 1) { + result = false; + break; } if (phdr.p_type == PT_GNU_STACK) { - if (phdr.p_flags == (PF_R | PF_W)) { - return true; - } else { - return false; - } + result = (phdr.p_flags == (PF_R | PF_W)); + break; } } } -// AARCH64 defaults to noexecstack. All others default to execstack. -#ifdef AARCH64 - return true; -#else - return false; -#endif + fclose(file); + return result; } -#endif +#endif // LINUX #endif // !_WINDOWS && !__APPLE__
--- a/hotspot/src/share/vm/utilities/elfFile.hpp Wed Jul 05 17:19:37 2017 +0200 +++ b/hotspot/src/share/vm/utilities/elfFile.hpp Wed Jul 05 11:03:19 2017 -0700 @@ -108,7 +108,7 @@ private: // sanity check, if the file is a real elf file - bool is_elf_file(Elf_Ehdr&); + static bool is_elf_file(Elf_Ehdr&); // load string tables from the elf file bool load_tables(); @@ -132,7 +132,7 @@ // Returns false if the elf file requires an executable stack, the stack flag // is not set at all, or if the file can not be read. // On systems other than linux it always returns false. - bool specifies_noexecstack() NOT_LINUX({ return false; }); + static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; }); protected: ElfFile* m_next;