annotate agent/src/os/bsd/salibelf.c @ 4582:b24386206122

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