annotate agent/src/os/bsd/symtab.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 436b4a3231bf
children 39432a1cefdd
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, 2010, 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 <unistd.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
26 #include <search.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
27 #include <stdlib.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 #include <db.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
30 #include <fcntl.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
31 #include "symtab.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
32 #include "salibelf.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
33
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
34
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
35 // ----------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
36 // functions for symbol lookups
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
37 // ----------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
38
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
39 struct elf_section {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
40 ELF_SHDR *c_shdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
41 void *c_data;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
42 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
43
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
44 struct elf_symbol {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
45 char *name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
46 uintptr_t offset;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
47 uintptr_t size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
48 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
49
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
50 typedef struct symtab {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
51 char *strs;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
52 size_t num_symbols;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
53 struct elf_symbol *symbols;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
54 DB* hash_table;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
55 } symtab_t;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
56
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
57 // read symbol table from given fd.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
58 struct symtab* build_symtab(int fd) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
59 ELF_EHDR ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
60 struct symtab* symtab = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
61
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
62 // Reading of elf header
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
63 struct elf_section *scn_cache = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
64 int cnt = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
65 ELF_SHDR* shbuf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
66 ELF_SHDR* cursct = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
67 ELF_PHDR* phbuf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
68 int symtab_found = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
69 int dynsym_found = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
70 uint32_t symsection = SHT_SYMTAB;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
71
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
72 uintptr_t baseaddr = (uintptr_t)-1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
73
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
74 lseek(fd, (off_t)0L, SEEK_SET);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
75 if (! read_elf_header(fd, &ehdr)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
76 // not an elf
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
77 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
78 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
79
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
80 // read ELF header
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
81 if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
82 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
83 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
84
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
85 baseaddr = find_base_address(fd, &ehdr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
86
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
87 scn_cache = calloc(ehdr.e_shnum, sizeof(*scn_cache));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
88 if (scn_cache == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
89 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
90 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
91
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
92 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
93 scn_cache[cnt].c_shdr = cursct;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
94 if (cursct->sh_type == SHT_SYMTAB ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
95 cursct->sh_type == SHT_STRTAB ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
96 cursct->sh_type == SHT_DYNSYM) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
97 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
98 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
99 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
100 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
101
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
102 if (cursct->sh_type == SHT_SYMTAB)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
103 symtab_found++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
104
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
105 if (cursct->sh_type == SHT_DYNSYM)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
106 dynsym_found++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
107
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
108 cursct++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
109 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
110
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
111 if (!symtab_found && dynsym_found)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
112 symsection = SHT_DYNSYM;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
113
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
114 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
115 ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
116
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
117 if (shdr->sh_type == symsection) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
118 ELF_SYM *syms;
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
119 int j, n;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
120 size_t size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
121
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
122 // FIXME: there could be multiple data buffers associated with the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
123 // same ELF section. Here we can handle only one buffer. See man page
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
124 // for elf_getdata on Solaris.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
125
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
126 // guarantee(symtab == NULL, "multiple symtab");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
127 symtab = calloc(1, sizeof(*symtab));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
128 if (symtab == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
129 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
130 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
131 // the symbol table
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
132 syms = (ELF_SYM *)scn_cache[cnt].c_data;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
133
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
134 // number of symbols
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
135 n = shdr->sh_size / shdr->sh_entsize;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
136
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
137 // create hash table, we use berkeley db to
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
138 // manipulate the hash table.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
139 symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
140 // guarantee(symtab->hash_table, "unexpected failure: dbopen");
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
141 if (symtab->hash_table == NULL)
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
142 goto bad;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
143
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
144 // shdr->sh_link points to the section that contains the actual strings
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
145 // for symbol names. the st_name field in ELF_SYM is just the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
146 // string table index. we make a copy of the string table so the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
147 // strings will not be destroyed by elf_end.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
148 size = scn_cache[shdr->sh_link].c_shdr->sh_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
149 symtab->strs = malloc(size);
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
150 if (symtab->strs == NULL)
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
151 goto bad;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
152 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
153
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
154 // allocate memory for storing symbol offset and size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
155 symtab->num_symbols = n;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
156 symtab->symbols = calloc(n , sizeof(*symtab->symbols));
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
157 if (symtab->symbols == NULL)
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
158 goto bad;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
159
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
160 // copy symbols info our symtab and enter them info the hash table
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
161 for (j = 0; j < n; j++, syms++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
162 DBT key, value;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
163 char *sym_name = symtab->strs + syms->st_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
164
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
165 // skip non-object and non-function symbols
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
166 int st_type = ELF_ST_TYPE(syms->st_info);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
167 if ( st_type != STT_FUNC && st_type != STT_OBJECT)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
168 continue;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
169 // skip empty strings and undefined symbols
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
170 if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
171
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
172 symtab->symbols[j].name = sym_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
173 symtab->symbols[j].offset = syms->st_value - baseaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
174 symtab->symbols[j].size = syms->st_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
175
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
176 key.data = sym_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
177 key.size = strlen(sym_name) + 1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
178 value.data = &(symtab->symbols[j]);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
179 value.size = sizeof(void *);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
180 (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
181 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
182 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
183 }
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
184 goto quit;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
185
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
186 bad:
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
187 destroy_symtab(symtab);
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
188 symtab = NULL;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
189
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
190 quit:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
191 if (shbuf) free(shbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
192 if (phbuf) free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
193 if (scn_cache) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
194 for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
195 if (scn_cache[cnt].c_data != NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
196 free(scn_cache[cnt].c_data);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
197 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
198 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
199 free(scn_cache);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
200 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
201 return symtab;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
202 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
203
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
204 void destroy_symtab(struct symtab* symtab) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
205 if (!symtab) return;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
206 if (symtab->strs) free(symtab->strs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
207 if (symtab->symbols) free(symtab->symbols);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
208 if (symtab->hash_table) {
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
209 (*symtab->hash_table->close)(symtab->hash_table);
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
210 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
211 free(symtab);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
212 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
213
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
214 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
215 const char *sym_name, int *sym_size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
216 DBT key, value;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
217 int ret;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
218
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
219 // library does not have symbol table
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
220 if (!symtab || !symtab->hash_table)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
221 return 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
222
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
223 key.data = (char*)(uintptr_t)sym_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
224 key.size = strlen(sym_name) + 1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
225 ret = (*symtab->hash_table->get)(symtab->hash_table, &key, &value, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
226 if (ret == 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
227 struct elf_symbol *sym = value.data;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
228 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
229 if (sym_size) *sym_size = sym->size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
230 return rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
231 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
232
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
233 return 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
234 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
235
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
236 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
237 uintptr_t* poffset) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
238 int n = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
239 if (!symtab) return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
240 for (; n < symtab->num_symbols; n++) {
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
241 struct elf_symbol* sym = &(symtab->symbols[n]);
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
242 if (sym->name != NULL &&
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
243 offset >= sym->offset && offset < sym->offset + sym->size) {
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
244 if (poffset) *poffset = (offset - sym->offset);
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
245 return sym->name;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
246 }
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
247 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
248 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
249 }