--- old/src/jdk.hotspot.agent/linux/native/libsaproc/libproc_impl.h 2020-08-04 09:37:24.494883744 +0900 +++ new/src/jdk.hotspot.agent/linux/native/libsaproc/libproc_impl.h 2020-08-04 09:37:24.349879527 +0900 @@ -67,6 +67,7 @@ off_t offset; // file offset of this mapping uintptr_t vaddr; // starting virtual address size_t memsz; // size of the mapping + uint32_t flags; // acces flags struct map_info* next; } map_info; --- old/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c 2020-08-04 09:37:24.801892672 +0900 +++ new/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c 2020-08-04 09:37:24.720890317 +0900 @@ -351,7 +351,7 @@ case PT_LOAD: { if (core_php->p_filesz != 0) { if (add_map_info(ph, ph->core->core_fd, core_php->p_offset, - core_php->p_vaddr, core_php->p_filesz) == NULL) goto err; + core_php->p_vaddr, core_php->p_filesz, core_php->p_flags) == NULL) goto err; } break; } @@ -390,10 +390,21 @@ if (existing_map == NULL){ if (add_map_info(ph, lib_fd, lib_php->p_offset, - target_vaddr, lib_php->p_memsz) == NULL) { + target_vaddr, lib_php->p_memsz, lib_php->p_flags) == NULL) { goto err; } + } else if (lib_php->p_flags != existing_map->flags) { + // Access flags for this memory region are different between the library + // and coredump. It might be caused by mprotect() call at runtime. + // We should respect the coredump. + continue; } else { + // Read only segments in ELF should not be any different from PT_LOAD segments + // in the coredump. + // Also the first page of the ELF header might be included + // in the coredump (See JDK-7133122). + // Thus we need to replace the PT_LOAD segment with the library version. + // // Coredump stores value of p_memsz elf field // rounded up to page boundary. @@ -460,7 +471,7 @@ case PT_LOAD: { // add only non-writable segments of non-zero filesz if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) { - if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err; + if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz, exec_php->p_flags) == NULL) goto err; } break; } --- old/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.h 2020-08-04 09:37:25.104901484 +0900 +++ new/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.h 2020-08-04 09:37:25.021899070 +0900 @@ -113,6 +113,7 @@ uint64_t offset; // file offset of this mapping uint64_t vaddr; // starting virtual address size_t memsz; // size of the mapping + uint32_t flags; // access flags struct map_info* next; } map_info; --- old/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c 2020-08-04 09:37:25.405910238 +0900 +++ new/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c 2020-08-04 09:37:25.324907882 +0900 @@ -248,7 +248,7 @@ print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i); goto err; } - if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize) == NULL) { + if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize, segcmd.flags) == NULL) { print_debug("Failed to add map_info at i = %d\n", i); goto err; } @@ -788,7 +788,7 @@ case PT_LOAD: { if (core_php->p_filesz != 0) { if (add_map_info(ph, ph->core->core_fd, core_php->p_offset, - core_php->p_vaddr, core_php->p_filesz) == NULL) goto err; + core_php->p_vaddr, core_php->p_filesz, core_php->p_flags) == NULL) goto err; } break; } @@ -827,7 +827,7 @@ if (existing_map == NULL){ if (add_map_info(ph, lib_fd, lib_php->p_offset, - target_vaddr, lib_php->p_filesz) == NULL) { + target_vaddr, lib_php->p_filesz, lib_php->p_flags) == NULL) { goto err; } } else { @@ -893,7 +893,7 @@ case PT_LOAD: { // add only non-writable segments of non-zero filesz if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) { - if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err; + if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz, exec_php->p_flags) == NULL) goto err; } break; } --- old/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c 2020-08-04 09:37:25.710919108 +0900 +++ new/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c 2020-08-04 09:37:25.629916752 +0900 @@ -41,6 +41,12 @@ #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" #endif +#ifdef PF_R +#define MAP_R_FLAG PF_R +#else +#define MAP_R_FLAG 0 +#endif + #ifdef LINUX // I have no idea why this function is called ps_pread() on macos but ps_pdread on linux. #define ps_pread ps_pdread @@ -113,7 +119,7 @@ } } -static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) { +static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz, uint32_t flags) { map_info* map; if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) { print_debug("can't allocate memory for map_info\n"); @@ -125,14 +131,15 @@ map->offset = offset; map->vaddr = vaddr; map->memsz = memsz; + map->flags = flags; return map; } // add map info with given fd, offset, vaddr and memsz map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset, - uintptr_t vaddr, size_t memsz) { + uintptr_t vaddr, size_t memsz, uint32_t flags) { map_info* map; - if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) { + if ((map = allocate_init_map(fd, offset, vaddr, memsz, flags)) == NULL) { return NULL; } @@ -149,7 +156,7 @@ uintptr_t vaddr, size_t memsz) { map_info* map; if ((map = allocate_init_map(ph->core->classes_jsa_fd, - offset, vaddr, memsz)) == NULL) { + offset, vaddr, memsz, MAP_R_FLAG)) == NULL) { return NULL; } --- old/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.h 2020-08-04 09:37:26.008927774 +0900 +++ new/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.h 2020-08-04 09:37:25.928925448 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr); map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset, - uintptr_t vaddr, size_t memsz); + uintptr_t vaddr, size_t memsz, uint32_t flags); void core_release(struct ps_prochandle* ph); bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size); bool init_classsharing_workaround(struct ps_prochandle* ph);