comparison agent/src/os/linux/ps_core.c @ 12290:1f42d3ec1759

7133122: SA throws sun.jvm.hotspot.debugger.UnmappedAddressException when it should not Summary: replace PT_LOAD segment with library segment when necessary Reviewed-by: dholmes, sla
author dsamersoff
date Sun, 22 Sep 2013 18:49:09 +0400
parents f6a055fcf47d
children 5705c7ee6dd7
comparison
equal deleted inserted replaced
12288:a7609ec351d6 12290:1f42d3ec1759
1 /* 1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
696 return false; 696 return false;
697 } 697 }
698 698
699 // read segments of a shared object 699 // read segments of a shared object
700 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) { 700 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
701 int i = 0; 701 int i = 0;
702 ELF_PHDR* phbuf; 702 ELF_PHDR* phbuf;
703 ELF_PHDR* lib_php = NULL; 703 ELF_PHDR* lib_php = NULL;
704 704
705 if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) 705 int page_size=sysconf(_SC_PAGE_SIZE);
706 return false; 706
707 707 if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
708 // we want to process only PT_LOAD segments that are not writable. 708 return false;
709 // i.e., text segments. The read/write/exec (data) segments would 709 }
710 // have been already added from core file segments. 710
711 for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { 711 // we want to process only PT_LOAD segments that are not writable.
712 if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { 712 // i.e., text segments. The read/write/exec (data) segments would
713 if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL) 713 // have been already added from core file segments.
714 goto err; 714 for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
715 } 715 if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
716 lib_php++; 716
717 } 717 uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
718 718 map_info *existing_map = core_lookup(ph, target_vaddr);
719 free(phbuf); 719
720 return true; 720 if (existing_map == NULL){
721 if (add_map_info(ph, lib_fd, lib_php->p_offset,
722 target_vaddr, lib_php->p_filesz) == NULL) {
723 goto err;
724 }
725 } else {
726 if ((existing_map->memsz != page_size) &&
727 (existing_map->fd != lib_fd) &&
728 (existing_map->memsz != lib_php->p_filesz)){
729
730 print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
731 target_vaddr, lib_php->p_filesz, lib_php->p_flags);
732 goto err;
733 }
734
735 /* replace PT_LOAD segment with library segment */
736 print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
737 existing_map->memsz, lib_php->p_filesz);
738
739 existing_map->fd = lib_fd;
740 existing_map->offset = lib_php->p_offset;
741 existing_map->memsz = lib_php->p_filesz;
742 }
743 }
744
745 lib_php++;
746 }
747
748 free(phbuf);
749 return true;
721 err: 750 err:
722 free(phbuf); 751 free(phbuf);
723 return false; 752 return false;
724 } 753 }
725 754
726 // process segments from interpreter (ld.so or ld-linux.so) 755 // process segments from interpreter (ld.so or ld-linux.so)
727 static bool read_interp_segments(struct ps_prochandle* ph) { 756 static bool read_interp_segments(struct ps_prochandle* ph) {
728 ELF_EHDR interp_ehdr; 757 ELF_EHDR interp_ehdr;