Mercurial > hg > truffle
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 } |