Mercurial > hg > graal-compiler
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; |