agent/src/os/bsd/salibelf.c

Mon, 28 Jul 2014 15:06:38 -0700

author
fzhinkin
date
Mon, 28 Jul 2014 15:06:38 -0700
changeset 6997
dbb05f6d93c4
parent 0
f90c822e73f8
permissions
-rw-r--r--

8051344: JVM crashed in Compile::start() during method parsing w/ UseRTMDeopt turned on
Summary: call rtm_deopt() only if there were no compilation bailouts before.
Reviewed-by: kvn

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "salibelf.h"
aoqi@0 26 #include <stdlib.h>
aoqi@0 27 #include <unistd.h>
aoqi@0 28 #include <string.h>
aoqi@0 29
aoqi@0 30 extern void print_debug(const char*,...);
aoqi@0 31
aoqi@0 32 // ELF file parsing helpers. Note that we do *not* use libelf here.
aoqi@0 33 int read_elf_header(int fd, ELF_EHDR* ehdr) {
aoqi@0 34 if (pread(fd, ehdr, sizeof (ELF_EHDR), 0) != sizeof (ELF_EHDR) ||
aoqi@0 35 memcmp(&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
aoqi@0 36 ehdr->e_version != EV_CURRENT) {
aoqi@0 37 return 0;
aoqi@0 38 }
aoqi@0 39 return 1;
aoqi@0 40 }
aoqi@0 41
aoqi@0 42 bool is_elf_file(int fd) {
aoqi@0 43 ELF_EHDR ehdr;
aoqi@0 44 return read_elf_header(fd, &ehdr);
aoqi@0 45 }
aoqi@0 46
aoqi@0 47 // read program header table of an ELF file
aoqi@0 48 ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr) {
aoqi@0 49 ELF_PHDR* phbuf = 0;
aoqi@0 50 // allocate memory for program header table
aoqi@0 51 size_t nbytes = hdr->e_phnum * hdr->e_phentsize;
aoqi@0 52
aoqi@0 53 if ((phbuf = (ELF_PHDR*) malloc(nbytes)) == NULL) {
aoqi@0 54 print_debug("can't allocate memory for reading program header table\n");
aoqi@0 55 return NULL;
aoqi@0 56 }
aoqi@0 57
aoqi@0 58 if (pread(fd, phbuf, nbytes, hdr->e_phoff) != nbytes) {
aoqi@0 59 print_debug("ELF file is truncated! can't read program header table\n");
aoqi@0 60 free(phbuf);
aoqi@0 61 return NULL;
aoqi@0 62 }
aoqi@0 63
aoqi@0 64 return phbuf;
aoqi@0 65 }
aoqi@0 66
aoqi@0 67 // read section header table of an ELF file
aoqi@0 68 ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr) {
aoqi@0 69 ELF_SHDR* shbuf = 0;
aoqi@0 70 // allocate memory for section header table
aoqi@0 71 size_t nbytes = hdr->e_shnum * hdr->e_shentsize;
aoqi@0 72
aoqi@0 73 if ((shbuf = (ELF_SHDR*) malloc(nbytes)) == NULL) {
aoqi@0 74 print_debug("can't allocate memory for reading section header table\n");
aoqi@0 75 return NULL;
aoqi@0 76 }
aoqi@0 77
aoqi@0 78 if (pread(fd, shbuf, nbytes, hdr->e_shoff) != nbytes) {
aoqi@0 79 print_debug("ELF file is truncated! can't read section header table\n");
aoqi@0 80 free(shbuf);
aoqi@0 81 return NULL;
aoqi@0 82 }
aoqi@0 83
aoqi@0 84 return shbuf;
aoqi@0 85 }
aoqi@0 86
aoqi@0 87 // read a particular section's data
aoqi@0 88 void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr) {
aoqi@0 89 void *buf = NULL;
aoqi@0 90 if (shdr->sh_type == SHT_NOBITS || shdr->sh_size == 0) {
aoqi@0 91 return buf;
aoqi@0 92 }
aoqi@0 93 if ((buf = calloc(shdr->sh_size, 1)) == NULL) {
aoqi@0 94 print_debug("can't allocate memory for reading section data\n");
aoqi@0 95 return NULL;
aoqi@0 96 }
aoqi@0 97 if (pread(fd, buf, shdr->sh_size, shdr->sh_offset) != shdr->sh_size) {
aoqi@0 98 free(buf);
aoqi@0 99 print_debug("section data read failed\n");
aoqi@0 100 return NULL;
aoqi@0 101 }
aoqi@0 102 return buf;
aoqi@0 103 }
aoqi@0 104
aoqi@0 105 uintptr_t find_base_address(int fd, ELF_EHDR* ehdr) {
aoqi@0 106 uintptr_t baseaddr = (uintptr_t)-1;
aoqi@0 107 int cnt;
aoqi@0 108 ELF_PHDR *phbuf, *phdr;
aoqi@0 109
aoqi@0 110 // read program header table
aoqi@0 111 if ((phbuf = read_program_header_table(fd, ehdr)) == NULL) {
aoqi@0 112 goto quit;
aoqi@0 113 }
aoqi@0 114
aoqi@0 115 // the base address of a shared object is the lowest vaddr of
aoqi@0 116 // its loadable segments (PT_LOAD)
aoqi@0 117 for (phdr = phbuf, cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
aoqi@0 118 if (phdr->p_type == PT_LOAD && phdr->p_vaddr < baseaddr) {
aoqi@0 119 baseaddr = phdr->p_vaddr;
aoqi@0 120 }
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 quit:
aoqi@0 124 if (phbuf) free(phbuf);
aoqi@0 125 return baseaddr;
aoqi@0 126 }

mercurial