comparison agent/src/os/bsd/symtab.c @ 4006:436b4a3231bf

7098194: integrate macosx-port changes Summary: Integrate bsd-port/hotspot and macosx-port/hotspot changes as of 2011.09.29. Reviewed-by: kvn, dholmes, never, phh Contributed-by: Christos Zoulas <christos@zoulas.com>, Greg Lewis <glewis@eyesbeyond.com>, Kurt Miller <kurt@intricatesoftware.com>, Alexander Strange <astrange@apple.com>, Mike Swingler <swingler@apple.com>, Roger Hoover <rhoover@apple.com>, Victor Hernandez <vhernandez@apple.com>, Pratik Solanki <psolanki@apple.com>
author dcubed
date Thu, 13 Oct 2011 09:35:42 -0700
parents f08d439fab8c
children 39432a1cefdd
comparison
equal deleted inserted replaced
4005:2ef3386478e6 4006:436b4a3231bf
114 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) { 114 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
115 ELF_SHDR *shdr = scn_cache[cnt].c_shdr; 115 ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
116 116
117 if (shdr->sh_type == symsection) { 117 if (shdr->sh_type == symsection) {
118 ELF_SYM *syms; 118 ELF_SYM *syms;
119 int j, n, rslt; 119 int j, n;
120 size_t size; 120 size_t size;
121 121
122 // FIXME: there could be multiple data buffers associated with the 122 // FIXME: there could be multiple data buffers associated with the
123 // same ELF section. Here we can handle only one buffer. See man page 123 // same ELF section. Here we can handle only one buffer. See man page
124 // for elf_getdata on Solaris. 124 // for elf_getdata on Solaris.
136 136
137 // create hash table, we use berkeley db to 137 // create hash table, we use berkeley db to
138 // manipulate the hash table. 138 // manipulate the hash table.
139 symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL); 139 symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
140 // guarantee(symtab->hash_table, "unexpected failure: dbopen"); 140 // guarantee(symtab->hash_table, "unexpected failure: dbopen");
141 if (symtab->hash_table == NULL)
142 goto bad;
141 143
142 // shdr->sh_link points to the section that contains the actual strings 144 // shdr->sh_link points to the section that contains the actual strings
143 // for symbol names. the st_name field in ELF_SYM is just the 145 // for symbol names. the st_name field in ELF_SYM is just the
144 // string table index. we make a copy of the string table so the 146 // string table index. we make a copy of the string table so the
145 // strings will not be destroyed by elf_end. 147 // strings will not be destroyed by elf_end.
146 size = scn_cache[shdr->sh_link].c_shdr->sh_size; 148 size = scn_cache[shdr->sh_link].c_shdr->sh_size;
147 symtab->strs = malloc(size); 149 symtab->strs = malloc(size);
150 if (symtab->strs == NULL)
151 goto bad;
148 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size); 152 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
149 153
150 // allocate memory for storing symbol offset and size; 154 // allocate memory for storing symbol offset and size;
151 symtab->num_symbols = n; 155 symtab->num_symbols = n;
152 symtab->symbols = calloc(n , sizeof(*symtab->symbols)); 156 symtab->symbols = calloc(n , sizeof(*symtab->symbols));
157 if (symtab->symbols == NULL)
158 goto bad;
153 159
154 // copy symbols info our symtab and enter them info the hash table 160 // copy symbols info our symtab and enter them info the hash table
155 for (j = 0; j < n; j++, syms++) { 161 for (j = 0; j < n; j++, syms++) {
156 DBT key, value; 162 DBT key, value;
157 char *sym_name = symtab->strs + syms->st_name; 163 char *sym_name = symtab->strs + syms->st_name;
173 value.size = sizeof(void *); 179 value.size = sizeof(void *);
174 (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0); 180 (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
175 } 181 }
176 } 182 }
177 } 183 }
184 goto quit;
185
186 bad:
187 destroy_symtab(symtab);
188 symtab = NULL;
178 189
179 quit: 190 quit:
180 if (shbuf) free(shbuf); 191 if (shbuf) free(shbuf);
181 if (phbuf) free(phbuf); 192 if (phbuf) free(phbuf);
182 if (scn_cache) { 193 if (scn_cache) {
193 void destroy_symtab(struct symtab* symtab) { 204 void destroy_symtab(struct symtab* symtab) {
194 if (!symtab) return; 205 if (!symtab) return;
195 if (symtab->strs) free(symtab->strs); 206 if (symtab->strs) free(symtab->strs);
196 if (symtab->symbols) free(symtab->symbols); 207 if (symtab->symbols) free(symtab->symbols);
197 if (symtab->hash_table) { 208 if (symtab->hash_table) {
198 symtab->hash_table->close(symtab->hash_table); 209 (*symtab->hash_table->close)(symtab->hash_table);
199 } 210 }
200 free(symtab); 211 free(symtab);
201 } 212 }
202 213
203 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, 214 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
217 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset); 228 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
218 if (sym_size) *sym_size = sym->size; 229 if (sym_size) *sym_size = sym->size;
219 return rslt; 230 return rslt;
220 } 231 }
221 232
222 quit:
223 return 0; 233 return 0;
224 } 234 }
225 235
226 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset, 236 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
227 uintptr_t* poffset) { 237 uintptr_t* poffset) {
228 int n = 0; 238 int n = 0;
229 if (!symtab) return NULL; 239 if (!symtab) return NULL;
230 for (; n < symtab->num_symbols; n++) { 240 for (; n < symtab->num_symbols; n++) {
231 struct elf_symbol* sym = &(symtab->symbols[n]); 241 struct elf_symbol* sym = &(symtab->symbols[n]);
232 if (sym->name != NULL && 242 if (sym->name != NULL &&
233 offset >= sym->offset && offset < sym->offset + sym->size) { 243 offset >= sym->offset && offset < sym->offset + sym->size) {
234 if (poffset) *poffset = (offset - sym->offset); 244 if (poffset) *poffset = (offset - sym->offset);
235 return sym->name; 245 return sym->name;
236 } 246 }
237 } 247 }
238 return NULL; 248 return NULL;
239 } 249 }