annotate agent/src/os/bsd/symtab.c @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 39432a1cefdd
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 /*
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3960
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>
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
31
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
32 #include "libproc_impl.h"
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
33 #include "symtab.h"
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
34 #ifndef __APPLE__
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
35 #include "salibelf.h"
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
36 #endif // __APPLE__
3960
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 // ----------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
40 // functions for symbol lookups
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
41 // ----------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
42
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
43 typedef struct symtab_symbol {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
44 char *name; // name like __ZThread_...
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
45 uintptr_t offset; // to loaded address
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
46 uintptr_t size; // size strlen
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
47 } symtab_symbol;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
48
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
49 typedef struct symtab {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
50 char *strs; // all symbols "__symbol1__'\0'__symbol2__...."
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
51 size_t num_symbols;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
52 DB* hash_table;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
53 symtab_symbol* symbols;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
54 } symtab_t;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
55
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
56 #ifdef __APPLE__
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
57
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
58 void build_search_table(symtab_t *symtab) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
59 int i;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
60 for (i = 0; i < symtab->num_symbols; i++) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
61 DBT key, value;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
62 key.data = symtab->symbols[i].name;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
63 key.size = strlen(key.data) + 1;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
64 value.data = &(symtab->symbols[i]);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
65 value.size = sizeof(symtab_symbol);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
66 (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
67
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
68 // check result
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
69 if (is_debug()) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
70 DBT rkey, rvalue;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
71 char* tmp = (char *)malloc(strlen(symtab->symbols[i].name) + 1);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
72 strcpy(tmp, symtab->symbols[i].name);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
73 rkey.data = tmp;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
74 rkey.size = strlen(tmp) + 1;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
75 (*symtab->hash_table->get)(symtab->hash_table, &rkey, &rvalue, 0);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
76 // we may get a copy back so compare contents
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
77 symtab_symbol *res = (symtab_symbol *)rvalue.data;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
78 if (strcmp(res->name, symtab->symbols[i].name) ||
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
79 res->offset != symtab->symbols[i].offset ||
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
80 res->size != symtab->symbols[i].size) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
81 print_debug("error to get hash_table value!\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
82 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
83 free(tmp);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
84 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
85 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
86 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
87
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
88 // read symbol table from given fd.
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
89 struct symtab* build_symtab(int fd) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
90 symtab_t* symtab = NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
91 int i;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
92 mach_header_64 header;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
93 off_t image_start;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
94
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
95 if (!get_arch_off(fd, CPU_TYPE_X86_64, &image_start)) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
96 print_debug("failed in get fat header\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
97 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
98 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
99 lseek(fd, image_start, SEEK_SET);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
100 if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
101 print_debug("reading header failed!\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
102 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
103 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
104 // header
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
105 if (header.magic != MH_MAGIC_64) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
106 print_debug("not a valid .dylib file\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
107 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
108 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
109
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
110 load_command lcmd;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
111 symtab_command symtabcmd;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
112 nlist_64 lentry;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
113
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
114 bool lcsymtab_exist = false;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
115
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
116 long filepos = ltell(fd);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
117 for (i = 0; i < header.ncmds; i++) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
118 lseek(fd, filepos, SEEK_SET);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
119 if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
120 print_debug("read load_command failed for file\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
121 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
122 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
123 filepos += lcmd.cmdsize; // next command position
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
124 if (lcmd.cmd == LC_SYMTAB) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
125 lseek(fd, -sizeof(load_command), SEEK_CUR);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
126 lcsymtab_exist = true;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
127 break;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
128 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
129 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
130 if (!lcsymtab_exist) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
131 print_debug("No symtab command found!\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
132 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
133 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
134 if (read(fd, (void *)&symtabcmd, sizeof(symtab_command)) != sizeof(symtab_command)) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
135 print_debug("read symtab_command failed for file");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
136 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
137 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
138 symtab = (symtab_t *)malloc(sizeof(symtab_t));
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
139 if (symtab == NULL) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
140 print_debug("out of memory: allocating symtab\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
141 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
142 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
143
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
144 // create hash table, we use berkeley db to
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
145 // manipulate the hash table.
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
146 symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
147 if (symtab->hash_table == NULL)
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
148 goto quit;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
149
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
150 symtab->num_symbols = symtabcmd.nsyms;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
151 symtab->symbols = (symtab_symbol *)malloc(sizeof(symtab_symbol) * symtab->num_symbols);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
152 symtab->strs = (char *)malloc(sizeof(char) * symtabcmd.strsize);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
153 if (symtab->symbols == NULL || symtab->strs == NULL) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
154 print_debug("out of memory: allocating symtab.symbol or symtab.strs\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
155 goto quit;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
156 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
157 lseek(fd, image_start + symtabcmd.symoff, SEEK_SET);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
158 for (i = 0; i < symtab->num_symbols; i++) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
159 if (read(fd, (void *)&lentry, sizeof(nlist_64)) != sizeof(nlist_64)) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
160 print_debug("read nlist_64 failed at %i\n", i);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
161 goto quit;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
162 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
163 symtab->symbols[i].offset = lentry.n_value;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
164 symtab->symbols[i].size = lentry.n_un.n_strx; // index
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
165 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
166
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
167 // string table
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
168 lseek(fd, image_start + symtabcmd.stroff, SEEK_SET);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
169 int size = read(fd, (void *)(symtab->strs), symtabcmd.strsize * sizeof(char));
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
170 if (size != symtabcmd.strsize * sizeof(char)) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
171 print_debug("reading string table failed\n");
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
172 goto quit;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
173 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
174
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
175 for (i = 0; i < symtab->num_symbols; i++) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
176 symtab->symbols[i].name = symtab->strs + symtab->symbols[i].size;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
177 if (i > 0) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
178 // fix size
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
179 symtab->symbols[i - 1].size = symtab->symbols[i].size - symtab->symbols[i - 1].size;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
180 print_debug("%s size = %d\n", symtab->symbols[i - 1].name, symtab->symbols[i - 1].size);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
181
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
182 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
183
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
184 if (i == symtab->num_symbols - 1) {
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
185 // last index
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
186 symtab->symbols[i].size =
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
187 symtabcmd.strsize - symtab->symbols[i].size;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
188 print_debug("%s size = %d\n", symtab->symbols[i].name, symtab->symbols[i].size);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
189 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
190 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
191
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
192 // build a hashtable for fast query
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
193 build_search_table(symtab);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
194 return symtab;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
195 quit:
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
196 if (symtab) destroy_symtab(symtab);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
197 return NULL;
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
198 }
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
199
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
200 #else // __APPLE__
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
201
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
202 struct elf_section {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
203 ELF_SHDR *c_shdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
204 void *c_data;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
205 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
206
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
207 // read symbol table from given fd.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
208 struct symtab* build_symtab(int fd) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
209 ELF_EHDR ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
210 struct symtab* symtab = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
211
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
212 // Reading of elf header
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
213 struct elf_section *scn_cache = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
214 int cnt = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
215 ELF_SHDR* shbuf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
216 ELF_SHDR* cursct = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
217 ELF_PHDR* phbuf = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
218 int symtab_found = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
219 int dynsym_found = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
220 uint32_t symsection = SHT_SYMTAB;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
221
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
222 uintptr_t baseaddr = (uintptr_t)-1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
223
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
224 lseek(fd, (off_t)0L, SEEK_SET);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
225 if (! read_elf_header(fd, &ehdr)) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
226 // not an elf
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
227 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
228 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
229
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
230 // read ELF header
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
231 if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
232 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
233 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
234
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
235 baseaddr = find_base_address(fd, &ehdr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
236
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
237 scn_cache = calloc(ehdr.e_shnum, sizeof(*scn_cache));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
238 if (scn_cache == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
239 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
240 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
241
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
242 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
243 scn_cache[cnt].c_shdr = cursct;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
244 if (cursct->sh_type == SHT_SYMTAB ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
245 cursct->sh_type == SHT_STRTAB ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
246 cursct->sh_type == SHT_DYNSYM) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
247 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
248 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
249 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
250 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
251
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
252 if (cursct->sh_type == SHT_SYMTAB)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
253 symtab_found++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
254
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
255 if (cursct->sh_type == SHT_DYNSYM)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
256 dynsym_found++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
257
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
258 cursct++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
259 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
260
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
261 if (!symtab_found && dynsym_found)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
262 symsection = SHT_DYNSYM;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
263
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
264 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
265 ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
266
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
267 if (shdr->sh_type == symsection) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
268 ELF_SYM *syms;
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
269 int j, n;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
270 size_t size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
271
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
272 // FIXME: there could be multiple data buffers associated with the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
273 // same ELF section. Here we can handle only one buffer. See man page
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
274 // for elf_getdata on Solaris.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
275
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
276 // guarantee(symtab == NULL, "multiple symtab");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
277 symtab = calloc(1, sizeof(*symtab));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
278 if (symtab == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
279 goto quit;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
280 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
281 // the symbol table
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
282 syms = (ELF_SYM *)scn_cache[cnt].c_data;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
283
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
284 // number of symbols
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
285 n = shdr->sh_size / shdr->sh_entsize;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
286
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
287 // create hash table, we use berkeley db to
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
288 // manipulate the hash table.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
289 symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
290 // guarantee(symtab->hash_table, "unexpected failure: dbopen");
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
291 if (symtab->hash_table == NULL)
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
292 goto bad;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
293
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
294 // shdr->sh_link points to the section that contains the actual strings
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
295 // for symbol names. the st_name field in ELF_SYM is just the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
296 // string table index. we make a copy of the string table so the
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
297 // strings will not be destroyed by elf_end.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
298 size = scn_cache[shdr->sh_link].c_shdr->sh_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
299 symtab->strs = malloc(size);
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
300 if (symtab->strs == NULL)
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
301 goto bad;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
302 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
303
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
304 // allocate memory for storing symbol offset and size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
305 symtab->num_symbols = n;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
306 symtab->symbols = calloc(n , sizeof(*symtab->symbols));
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
307 if (symtab->symbols == NULL)
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
308 goto bad;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
309
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
310 // copy symbols info our symtab and enter them info the hash table
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
311 for (j = 0; j < n; j++, syms++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
312 DBT key, value;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
313 char *sym_name = symtab->strs + syms->st_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
314
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
315 // skip non-object and non-function symbols
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
316 int st_type = ELF_ST_TYPE(syms->st_info);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
317 if ( st_type != STT_FUNC && st_type != STT_OBJECT)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
318 continue;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
319 // skip empty strings and undefined symbols
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
320 if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
321
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
322 symtab->symbols[j].name = sym_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
323 symtab->symbols[j].offset = syms->st_value - baseaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
324 symtab->symbols[j].size = syms->st_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
325
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
326 key.data = sym_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
327 key.size = strlen(sym_name) + 1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
328 value.data = &(symtab->symbols[j]);
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
329 value.size = sizeof(symtab_symbol);
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
330 (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
331 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
332 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
333 }
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
334 goto quit;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
335
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
336 bad:
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
337 destroy_symtab(symtab);
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
338 symtab = NULL;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
339
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
340 quit:
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
341 if (shbuf) free(shbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
342 if (phbuf) free(phbuf);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
343 if (scn_cache) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
344 for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
345 if (scn_cache[cnt].c_data != NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
346 free(scn_cache[cnt].c_data);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
347 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
348 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
349 free(scn_cache);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
350 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
351 return symtab;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
352 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
353
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
354 #endif // __APPLE__
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
355
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
356 void destroy_symtab(symtab_t* symtab) {
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
357 if (!symtab) return;
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
358 free(symtab->strs);
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
359 free(symtab->symbols);
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
360 free(symtab);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
361 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
362
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
363 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, const char *sym_name, int *sym_size) {
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
364 DBT key, value;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
365 int ret;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
366
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
367 // library does not have symbol table
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
368 if (!symtab || !symtab->hash_table) {
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
369 return 0;
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
370 }
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
371
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
372 key.data = (char*)(uintptr_t)sym_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
373 key.size = strlen(sym_name) + 1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
374 ret = (*symtab->hash_table->get)(symtab->hash_table, &key, &value, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
375 if (ret == 0) {
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
376 symtab_symbol *sym = value.data;
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
377 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
378 if (sym_size) *sym_size = sym->size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
379 return rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
380 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
381
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
382 return 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
383 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
384
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
385 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
386 uintptr_t* poffset) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
387 int n = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
388 if (!symtab) return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
389 for (; n < symtab->num_symbols; n++) {
8750
39432a1cefdd 8003348: SA can not read core file on OS
minqi
parents: 4006
diff changeset
390 symtab_symbol* sym = &(symtab->symbols[n]);
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
391 if (sym->name != NULL &&
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
392 offset >= sym->offset && offset < sym->offset + sym->size) {
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
393 if (poffset) *poffset = (offset - sym->offset);
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
394 return sym->name;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3960
diff changeset
395 }
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
396 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
397 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
398 }