1 /*
2 * mpatrol
3 * A library for controlling and tracing dynamic memory allocations.
4 * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307, USA.
20 */
21
22
23 /*
24 * Symbol tables. The implementation of reading symbols from executable files
25 * may also interface with access libraries which support other file formats.
26 * This module may also have to liaise with the dynamic linker (or equivalent)
27 * in order to obtain symbols from shared objects. A very useful book on the
28 * various different object file and library formats that exist is Linkers &
29 * Loaders, First Edition by John R. Levine (Morgan Kaufmann Publishers, 2000,
30 * ISBN 1-558-60496-0).
31 */
32
33
34 #include "symbol.h"
35 #include "diag.h"
36 #include "utils.h"
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #if FORMAT == FORMAT_AOUT || FORMAT == FORMAT_COFF || \
41 FORMAT == FORMAT_XCOFF || FORMAT == FORMAT_ELF32 || \
42 FORMAT == FORMAT_ELF64 || FORMAT == FORMAT_BFD
43 #include <fcntl.h>
44 #include <unistd.h>
45 #if FORMAT == FORMAT_AOUT
46 #include <a.out.h>
47 #elif FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF
48 #include <a.out.h>
49 #if SYSTEM == SYSTEM_LYNXOS
50 #include <coff.h>
51 #ifndef ISCOFF
52 #define ISCOFF(m) ((m) == COFFMAGICNUM)
53 #endif /* ISCOFF */
54 #ifndef ISFCN
55 #define ISFCN(t) (((t) & 0x30) == (DT_FCN << 4))
56 #endif /* ISFCN */
57 #ifndef n_name
58 #define n_name _n._n_name
59 #endif /* n_name */
60 #else /* SYSTEM */
61 #if SYSTEM == SYSTEM_AIX
62 #ifdef FREAD
63 #undef FREAD
64 #endif /* FREAD */
65 #ifdef FWRITE
66 #undef FWRITE
67 #endif /* FWRITE */
68 #ifndef ISCOFF
69 #define ISCOFF(m) (((m) == U800TOCMAGIC) || ((m) == U802TOCMAGIC))
70 #endif /* ISCOFF */
71 #endif /* SYSTEM */
72 #include <ldfcn.h>
73 #endif /* SYSTEM */
74 #elif FORMAT == FORMAT_ELF32 || FORMAT == FORMAT_ELF64
75 #include <libelf/libelf.h>
76 #elif FORMAT == FORMAT_BFD
77 #include <bfd.h>
78 #endif /* FORMAT */
79 #endif /* FORMAT */
80 #if DYNLINK == DYNLINK_AIX
81 /* The shared libraries that an AIX executable has loaded can be obtained via
82 * the loadquery() function.
83 */
84 #include <sys/types.h>
85 #include <sys/ldr.h>
86 #elif DYNLINK == DYNLINK_BSD
87 /* The BSD a.out dynamic linker is based on the original SunOS implementation
88 * and is the precursor to the SVR4 ELF dynamic linker. Most BSD systems now
89 * use ELF so this is for SunOS and the BSD systems that still use a.out.
90 */
91 #include <sys/types.h>
92 #include <link.h>
93 #elif DYNLINK == DYNLINK_HPUX
94 /* The HP/UX dynamic linker support routines are available for use even by
95 * statically linked programs.
96 */
97 #include <dl.h>
98 #elif DYNLINK == DYNLINK_IRIX
99 /* IRIX doesn't have a conventional SVR4 dynamic linker and so does not have the
100 * same interface for accessing information about any required shared objects at
101 * run-time.
102 */
103 #include <obj.h>
104 #include <obj_list.h>
105 #elif DYNLINK == DYNLINK_OSF
106 /* The shared libraries that an OSF executable has loaded can be obtained via
107 * the ldr_inq_module() and ldr_inq_region() functions.
108 */
109 #include <loader.h>
110 #elif DYNLINK == DYNLINK_SVR4
111 /* Despite the fact that Linux is now ELF-based, libelf seems to be missing from
112 * many recent distributions and so we must use the GNU BFD library to read the
113 * symbols from the object files and libraries. However, we still need the ELF
114 * definitions for reading the internal structures of the dynamic linker.
115 */
116 /*#include <elf.h>*/
117 #elif DYNLINK == DYNLINK_WINDOWS
118 /* We use the imagehlp library on Windows platforms to obtain information about
119 * the symbols loaded from third-party and system DLLs. We can also use it to
120 * obtain information about any symbols contained in the executable file and
121 * program database if COFF or CodeView debugging information is being used.
122 */
123 #include <windows.h>
124 #include <imagehlp.h>
125 #endif /* DYNLINK */
126
127
128 #if MP_IDENT_SUPPORT
129 #ident "$Id: symbol.c,v 1.62 2002/01/08 20:13:59 graeme Exp $"
130 #else /* MP_IDENT_SUPPORT */
131 static MP_CONST MP_VOLATILE char *symbol_id = "$Id: symbol.c,v 1.62 2002/01/08 20:13:59 graeme Exp $";
132 #endif /* MP_IDENT_SUPPORT */
133
134
135 #if DYNLINK == DYNLINK_SVR4
136 /* These definitions are not always defined in ELF header files on all
137 * systems so we define them here as they are documented in most
138 * System V ABI documents.
139 */
140
141 #ifndef DT_NULL
142 #define DT_NULL 0
143 #define DT_DEBUG 21
144
145 #if ENVIRON == ENVIRON_64
146 typedef struct Elf64_Dyn
147 {
148 Elf64_Xword d_tag; /* tag indicating type of data stored */
149 union
150 {
151 Elf64_Xword d_val; /* data is a value */
152 Elf64_Addr d_ptr; /* data is a pointer */
153 }
154 d_un;
155 }
156 Elf64_Dyn;
157 #else /* ENVIRON */
158 typedef struct Elf32_Dyn
159 {
160 Elf32_Sword d_tag; /* tag indicating type of data stored */
161 union
162 {
163 Elf32_Word d_val; /* data is a value */
164 Elf32_Addr d_ptr; /* data is a pointer */
165 }
166 d_un;
167 }
168 Elf32_Dyn;
169 #endif /* ENVIRON */
170 #endif /* DT_NULL */
171 #endif /* DYNLINK */
172
173
174 #if DYNLINK == DYNLINK_IRIX
175 /* This structure represents an N32 ABI shared object as opposed to an O32 ABI
176 * shared object, and is defined on IRIX 6.0 and above platforms as
177 * Elf32_Obj_Info. In order for us to compile on earlier IRIX platforms we
178 * define this structure here, but under a different name so as to avoid a
179 * naming clash on IRIX 6.0 and later.
180 */
181
182 typedef struct objectinfo
183 {
184 Elf32_Word magic; /* N32 ABI shared object */
185 Elf32_Word size; /* size of this structure */
186 Elf32_Addr next; /* next shared object */
187 Elf32_Addr prev; /* previous shared object */
188 Elf32_Addr ehdr; /* address of object file header */
189 Elf32_Addr ohdr; /* original address of object file header */
190 Elf32_Addr name; /* filename of shared object */
191 Elf32_Word length; /* length of filename of shared object */
192 }
193 objectinfo;
194 #elif DYNLINK == DYNLINK_SVR4
195 /* This is a structure that is internal to the dynamic linker on ELF systems,
196 * and so it is not always guaranteed to be the same. We try to rely on this
197 * definition here for portability's sake as it is not publicly declared in
198 * all ELF header files.
199 */
200
201 typedef struct dynamiclink
202 {
203 size_t base; /* virtual address of shared object */
204 char *name; /* filename of shared object */
205 #if ENVIRON == ENVIRON_64
206 Elf64_Dyn *dyn; /* dynamic linking information */
207 #else /* ENVIRON */
208 Elf32_Dyn *dyn; /* dynamic linking information */
209 #endif /* ENVIRON */
210 struct dynamiclink *next; /* pointer to next shared object */
211 }
212 dynamiclink;
213 #elif DYNLINK == DYNLINK_WINDOWS
214 /* This structure is used to pass information to the callback function
215 * called by SymEnumerateSymbols().
216 */
217
218 typedef struct syminfo
219 {
220 symhead *syms; /* pointer to symbol table */
221 char *file; /* filename of module */
222 }
223 syminfo;
224
225
226 /* This structure is used to pass information to the callback function
227 * called by SymEnumerateModules().
228 */
229
230 typedef struct modinfo
231 {
232 symhead *syms; /* pointer to symbol table */
233 size_t index; /* index of module */
234 char libs; /* only read DLLs */
235 }
236 modinfo;
237 #endif /* DYNLINK */
238
239
240 #if FORMAT == FORMAT_BFD
241 /* This structure is used to maintain a list of access library handles for
242 * the purposes of mapping return addresses to line numbers.
243 */
244
245 typedef struct objectfile
246 {
247 struct objectfile *next; /* pointer to next object file */
248 bfd *file; /* access library handle */
249 asymbol **symbols; /* pointer to symbols */
250 size_t base; /* virtual address of object file */
251 }
252 objectfile;
253
254
255 /* This structure is used when searching for source locations corresponding
256 * to virtual addresses by looking at debugging information embedded in an
257 * object file.
258 */
259
260 typedef struct sourcepos
261 {
262 bfd_vma addr; /* virtual address to search for */
263 asymbol **symbols; /* pointer to symbols */
264 size_t base; /* virtual address of object file */
265 char *func; /* function name */
266 char *file; /* file name */
267 unsigned int line; /* line number */
268 char found; /* found flag */
269 }
270 sourcepos;
271 #endif /* FORMAT */
272
273
274 #ifdef __cplusplus
275 extern "C"
276 {
277 #endif /* __cplusplus */
278
279
280 #if DYNLINK == DYNLINK_BSD
281 /* The declaration of the _DYNAMIC symbol, which allows us direct access to the
282 * dynamic linker's internal data structures. This is set up in crt0 and will
283 * be NULL in an object that does not need dynamic linking.
284 */
285 #if SYSTEM == SYSTEM_SUNOS
286 extern struct link_dynamic _DYNAMIC;
287 #else /* SYSTEM */
288 extern struct _dynamic _DYNAMIC;
289 #endif /* SYSTEM */
290 #elif DYNLINK == DYNLINK_IRIX
291 /* The __rld_obj_head symbol is always defined in IRIX and points to the first
292 * entry in a list of shared object files that are required by the program. For
293 * statically linked programs this will either be NULL or will only contain the
294 * entry for the program itself.
295 */
296 extern struct obj_list *__rld_obj_head;
297 #elif DYNLINK == DYNLINK_SVR4
298 /* The declaration of the _DYNAMIC symbol, which allows us direct access to the
299 * dynamic linker's internal data structures. We make it have weak visibility
300 * so that it is always defined, even in the statically linked case. It is
301 * declared as a function because some compilers only allow weak function
302 * symbols. Another alternative would be to declare it as a common symbol, but
303 * that wouldn't work under C++ and many libc shared objects have it defined as
304 * a text symbol.
305 */
306
307 #pragma weak _DYNAMIC
308 void _DYNAMIC(void);
309 #endif /* DYNLINK */
310
311
312 /* Initialise the fields of a symhead so that the symbol table becomes empty.
313 */
314
315 MP_GLOBAL
316 void
__mp_newsymbols(symhead * y,heaphead * h,void * i)317 __mp_newsymbols(symhead *y, heaphead *h, void *i)
318 {
319 struct { char x; symnode y; } z;
320 long n;
321
322 y->heap = h;
323 /* Determine the minimum alignment for a symbol node on this system
324 * and force the alignment to be a power of two. This information
325 * is used when initialising the slot table.
326 */
327 n = (char *) &z.y - &z.x;
328 __mp_newstrtab(&y->strings, h);
329 __mp_newslots(&y->table, sizeof(symnode), __mp_poweroftwo(n));
330 __mp_newtree(&y->itree);
331 __mp_newtree(&y->dtree);
332 y->size = 0;
333 y->hhead = y->htail = NULL;
334 y->inits = i;
335 y->prot = MA_NOACCESS;
336 y->protrecur = 0;
337 y->lineinfo = 0;
338 }
339
340
341 /* Close all access library handles.
342 */
343
344 MP_GLOBAL
345 void
__mp_closesymbols(symhead * y)346 __mp_closesymbols(symhead *y)
347 {
348 #if FORMAT == FORMAT_BFD
349 objectfile *n, *p;
350 #endif /* FORMAT */
351
352 #if FORMAT == FORMAT_BFD
353 for (n = (objectfile *) y->hhead; n != NULL; n = p)
354 {
355 p = n->next;
356 bfd_close(n->file);
357 free(n->symbols);
358 free(n);
359 }
360 #endif /* FORMAT */
361 y->hhead = y->htail = NULL;
362 }
363
364
365 /* Forget all data currently in the symbol table.
366 */
367
368 MP_GLOBAL
369 void
__mp_deletesymbols(symhead * y)370 __mp_deletesymbols(symhead *y)
371 {
372 /* We don't need to explicitly free any memory as this is dealt with
373 * at a lower level by the heap manager.
374 */
375 y->heap = NULL;
376 __mp_deletestrtab(&y->strings);
377 y->table.free = NULL;
378 y->table.size = 0;
379 __mp_newtree(&y->itree);
380 __mp_newtree(&y->dtree);
381 y->size = 0;
382 y->inits = NULL;
383 y->prot = MA_NOACCESS;
384 y->protrecur = 0;
385 }
386
387
388 /* Allocate a new symbol node.
389 */
390
391 static
392 symnode *
getsymnode(symhead * y)393 getsymnode(symhead *y)
394 {
395 symnode *n;
396 heapnode *p;
397
398 /* If we have no more symbol node slots left then we must allocate
399 * some more memory for them. An extra MP_ALLOCFACTOR pages of memory
400 * should suffice.
401 */
402 if ((n = (symnode *) __mp_getslot(&y->table)) == NULL)
403 {
404 if ((p = __mp_heapalloc(y->heap, y->heap->memory.page * MP_ALLOCFACTOR,
405 y->table.entalign, 1)) == NULL)
406 return NULL;
407 __mp_initslots(&y->table, p->block, p->size);
408 n = (symnode *) __mp_getslot(&y->table);
409 __mp_treeinsert(&y->itree, &n->index.node, (unsigned long) p->block);
410 n->index.block = p->block;
411 n->index.size = p->size;
412 y->size += p->size;
413 n = (symnode *) __mp_getslot(&y->table);
414 }
415 return n;
416 }
417
418
419 #if FORMAT == FORMAT_AOUT || FORMAT == FORMAT_COFF || \
420 FORMAT == FORMAT_XCOFF || FORMAT == FORMAT_ELF32 || \
421 FORMAT == FORMAT_ELF64 || FORMAT == FORMAT_BFD
422 /* Decide whether to store a symbol by looking at its name.
423 */
424
425 static
426 int
addsymname(char ** s)427 addsymname(char **s)
428 {
429 /* We don't bother storing a symbol which has no name or whose name
430 * contains a '$', '@' or a '.', although GNU C++ destructors begin
431 * with `_._'. However, in XCOFF the symbol name is likely to be the
432 * name of a CSECT beginning with a '.' and not the original name of
433 * the function, so we skip the first character. In addition, the
434 * HP/UX $START$ symbol contains dollar characters but we don't want
435 * to bother allowing any other symbols containing dollars.
436 */
437 if ((*s != NULL) && (**s != '\0') &&
438 #if ((SYSTEM == SYSTEM_AIX || SYSTEM == SYSTEM_LYNXOS) && \
439 (ARCH == ARCH_POWER || ARCH == ARCH_POWERPC)) || FORMAT == FORMAT_XCOFF
440 (*(*s)++ == '.') && (strcmp(*s, "text") != 0) &&
441 #endif /* SYSTEM && ARCH && FORMAT */
442 ((strncmp(*s, "_._", 3) == 0) ||
443 #if SYSTEM == SYSTEM_HPUX
444 (strcmp(*s, "$START$") == 0) ||
445 #endif /* SYSTEM */
446 !strpbrk(*s, "$@.")))
447 return 1;
448 return 0;
449 }
450 #endif /* FORMAT */
451
452
453 #if FORMAT == FORMAT_AOUT
454 /* Allocate a new symbol node for a given a.out symbol.
455 */
456
457 static
458 int
addsymbol(symhead * y,struct nlist * p,char * f,char * s,size_t b)459 addsymbol(symhead *y, struct nlist *p, char *f, char *s, size_t b)
460 {
461 symnode *n;
462 char *r;
463 size_t a;
464
465 a = b + p->n_value;
466 /* We don't allocate a symbol node for symbols which have a virtual
467 * address of zero.
468 */
469 if (addsymname(&s) && (a > 0))
470 {
471 if ((n = getsymnode(y)) == NULL)
472 return 0;
473 if ((r = __mp_addstring(&y->strings, s)) == NULL)
474 {
475 __mp_freeslot(&y->table, n);
476 return 0;
477 }
478 __mp_treeinsert(&y->dtree, &n->data.node, a);
479 n->data.file = f;
480 n->data.name = r;
481 n->data.addr = (void *) a;
482 /* The a.out file format doesn't record symbol sizes, so we have
483 * to rely on the assumption that a function symbol ends at the
484 * beginning of the next function symbol. This will be calculated
485 * in __mp_fixsymbols().
486 */
487 n->data.size = 0;
488 n->data.index = 0;
489 n->data.offset = 0;
490 /* The linkage information is required for when we look up a symbol.
491 */
492 n->data.flags = p->n_type;
493 #if MP_INITFUNC_SUPPORT
494 /* Check to see if this function should be called when the mpatrol
495 * library is initialised or terminated.
496 */
497 if ((strncmp(r, "__mp_init_", 10) == 0) && (r[10] != '\0'))
498 __mp_atinit((infohead *) y->inits, (void (*)(void)) a);
499 else if ((strncmp(r, "__mp_fini_", 10) == 0) && (r[10] != '\0'))
500 __mp_atfini((infohead *) y->inits, (void (*)(void)) a);
501 #endif /* MP_INITFUNC_SUPPORT */
502 }
503 return 1;
504 }
505 #elif FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF
506 /* Allocate a new symbol node for a given COFF or XCOFF symbol.
507 */
508
509 static
510 int
addsymbol(symhead * y,SYMENT * p,char * f,char * s,size_t b)511 addsymbol(symhead *y, SYMENT *p, char *f, char *s, size_t b)
512 {
513 AUXENT *e;
514 symnode *n;
515 char *r;
516 size_t a;
517
518 a = b + p->n_value;
519 /* We don't allocate a symbol node for symbols which have a virtual
520 * address of zero and we only remember symbols that are declared
521 * statically or externally visible.
522 */
523 if (addsymname(&s) && (a > 0) &&
524 #if FORMAT == FORMAT_XCOFF
525 (ISFCN(p->n_type) || (p->n_sclass == C_EXT)))
526 #else /* FORMAT */
527 ((p->n_sclass == C_STAT) || (p->n_sclass == C_EXT)))
528 #endif /* FORMAT */
529 {
530 if ((n = getsymnode(y)) == NULL)
531 return 0;
532 if ((r = __mp_addstring(&y->strings, s)) == NULL)
533 {
534 __mp_freeslot(&y->table, n);
535 return 0;
536 }
537 __mp_treeinsert(&y->dtree, &n->data.node, a);
538 n->data.file = f;
539 n->data.name = r;
540 n->data.addr = (void *) a;
541 /* Attempt to figure out the size of the symbol.
542 */
543 if (p->n_numaux > 0)
544 {
545 e = (AUXENT *) ((char *) p + SYMESZ);
546 if (ISFCN(p->n_type))
547 n->data.size = e->x_sym.x_misc.x_fsize;
548 else
549 n->data.size = e->x_sym.x_misc.x_lnsz.x_size;
550 }
551 else
552 n->data.size = 0;
553 n->data.index = 0;
554 n->data.offset = 0;
555 /* The linkage information is required for when we look up a symbol.
556 */
557 n->data.flags = p->n_sclass;
558 #if MP_INITFUNC_SUPPORT
559 /* Check to see if this function should be called when the mpatrol
560 * library is initialised or terminated.
561 */
562 if ((strncmp(r, "__mp_init_", 10) == 0) && (r[10] != '\0'))
563 __mp_atinit((infohead *) y->inits, (void (*)(void)) a);
564 else if ((strncmp(r, "__mp_fini_", 10) == 0) && (r[10] != '\0'))
565 __mp_atfini((infohead *) y->inits, (void (*)(void)) a);
566 #endif /* MP_INITFUNC_SUPPORT */
567 }
568 return 1;
569 }
570 #elif FORMAT == FORMAT_ELF32
571 /* Allocate a new symbol node for a given ELF32 symbol.
572 */
573
574 static
575 int
addsymbol(symhead * y,Elf32_Sym * p,char * f,char * s,size_t b)576 addsymbol(symhead *y, Elf32_Sym *p, char *f, char *s, size_t b)
577 {
578 symnode *n;
579 char *r;
580 size_t a;
581 unsigned char t;
582
583 a = b + p->st_value;
584 /* We don't allocate a symbol node for symbols which have a virtual
585 * address of zero or are of object type.
586 */
587 if (addsymname(&s) && (a > 0) &&
588 (((t = ELF32_ST_TYPE(p->st_info)) == STT_NOTYPE) || (t == STT_FUNC)))
589 {
590 if ((n = getsymnode(y)) == NULL)
591 return 0;
592 if ((r = __mp_addstring(&y->strings, s)) == NULL)
593 {
594 __mp_freeslot(&y->table, n);
595 return 0;
596 }
597 __mp_treeinsert(&y->dtree, &n->data.node, a);
598 n->data.file = f;
599 n->data.name = r;
600 n->data.addr = (void *) a;
601 n->data.size = p->st_size;
602 n->data.index = 0;
603 n->data.offset = 0;
604 /* The linkage information is required for when we look up a symbol.
605 */
606 n->data.flags = ELF32_ST_BIND(p->st_info);
607 #if MP_INITFUNC_SUPPORT
608 /* Check to see if this function should be called when the mpatrol
609 * library is initialised or terminated.
610 */
611 if ((strncmp(r, "__mp_init_", 10) == 0) && (r[10] != '\0'))
612 __mp_atinit((infohead *) y->inits, (void (*)(void)) a);
613 else if ((strncmp(r, "__mp_fini_", 10) == 0) && (r[10] != '\0'))
614 __mp_atfini((infohead *) y->inits, (void (*)(void)) a);
615 #endif /* MP_INITFUNC_SUPPORT */
616 }
617 return 1;
618 }
619 #elif FORMAT == FORMAT_ELF64
620 /* Allocate a new symbol node for a given ELF64 symbol.
621 */
622
623 static
624 int
addsymbol(symhead * y,Elf64_Sym * p,char * f,char * s,size_t b)625 addsymbol(symhead *y, Elf64_Sym *p, char *f, char *s, size_t b)
626 {
627 symnode *n;
628 char *r;
629 size_t a;
630 unsigned char t;
631
632 a = b + p->st_value;
633 /* We don't allocate a symbol node for symbols which have a virtual
634 * address of zero or are of object type.
635 */
636 if (addsymname(&s) && (a > 0) &&
637 (((t = ELF64_ST_TYPE(p->st_info)) == STT_NOTYPE) || (t == STT_FUNC)))
638 {
639 if ((n = getsymnode(y)) == NULL)
640 return 0;
641 if ((r = __mp_addstring(&y->strings, s)) == NULL)
642 {
643 __mp_freeslot(&y->table, n);
644 return 0;
645 }
646 __mp_treeinsert(&y->dtree, &n->data.node, a);
647 n->data.file = f;
648 n->data.name = r;
649 n->data.addr = (void *) a;
650 n->data.size = p->st_size;
651 n->data.index = 0;
652 n->data.offset = 0;
653 /* The linkage information is required for when we look up a symbol.
654 */
655 n->data.flags = ELF64_ST_BIND(p->st_info);
656 #if MP_INITFUNC_SUPPORT
657 /* Check to see if this function should be called when the mpatrol
658 * library is initialised or terminated.
659 */
660 if ((strncmp(r, "__mp_init_", 10) == 0) && (r[10] != '\0'))
661 __mp_atinit((infohead *) y->inits, (void (*)(void)) a);
662 else if ((strncmp(r, "__mp_fini_", 10) == 0) && (r[10] != '\0'))
663 __mp_atfini((infohead *) y->inits, (void (*)(void)) a);
664 #endif /* MP_INITFUNC_SUPPORT */
665 }
666 return 1;
667 }
668 #elif FORMAT == FORMAT_BFD
669 /* Allocate a new symbol node for a given BFD symbol.
670 */
671
672 static
673 int
addsymbol(symhead * y,asymbol * p,char * f,char * s,size_t b)674 addsymbol(symhead *y, asymbol *p, char *f, char *s, size_t b)
675 {
676 symnode *n;
677 char *r;
678 size_t a;
679
680 a = b + (size_t) p->value;
681 /* We don't allocate a symbol node for symbols which have a virtual
682 * address of zero and we only remember symbols that are declared
683 * statically, externally or weakly visible.
684 */
685 if (addsymname(&s) && (a > 0) &&
686 (p->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_WEAK)))
687 {
688 if ((n = getsymnode(y)) == NULL)
689 return 0;
690 if ((r = __mp_addstring(&y->strings, s)) == NULL)
691 {
692 __mp_freeslot(&y->table, n);
693 return 0;
694 }
695 __mp_treeinsert(&y->dtree, &n->data.node, a);
696 n->data.file = f;
697 n->data.name = r;
698 n->data.addr = (void *) a;
699 /* The BFD library doesn't seem to support reading symbol sizes,
700 * so we have to rely on the assumption that a function symbol
701 * ends at the beginning of the next function symbol. This will
702 * be calculated in __mp_fixsymbols().
703 */
704 n->data.size = 0;
705 n->data.index = 0;
706 n->data.offset = 0;
707 /* The linkage information is required for when we look up a symbol.
708 */
709 n->data.flags = p->flags;
710 #if MP_INITFUNC_SUPPORT
711 /* Check to see if this function should be called when the mpatrol
712 * library is initialised or terminated.
713 */
714 if ((strncmp(r, "__mp_init_", 10) == 0) && (r[10] != '\0'))
715 __mp_atinit((infohead *) y->inits, (void (*)(void)) a);
716 else if ((strncmp(r, "__mp_fini_", 10) == 0) && (r[10] != '\0'))
717 __mp_atfini((infohead *) y->inits, (void (*)(void)) a);
718 #endif /* MP_INITFUNC_SUPPORT */
719 }
720 return 1;
721 }
722 #endif /* FORMAT */
723
724
725 #if DYNLINK == DYNLINK_WINDOWS
726 /* The callback function called to allocate a new symbol node for each
727 * symbol located in a module by the imagehlp library.
728 */
729
730 static
731 int __stdcall
addsym(char * s,unsigned long a,unsigned long l,void * p)732 addsym(char *s, unsigned long a, unsigned long l, void *p)
733 {
734 syminfo *i;
735 symhead *y;
736 symnode *n;
737 char *r;
738
739 i = (syminfo *) p;
740 y = i->syms;
741 /* We don't bother storing a symbol which has no name or which has a
742 * virtual address of zero. Unfortunately, the imagehlp library does
743 * not provide information about the types of symbols so we will just
744 * have to add any symbols representing objects here as well.
745 */
746 if ((s != NULL) && (*s != '\0') && (a > 0))
747 {
748 if ((n = getsymnode(y)) == NULL)
749 return 0;
750 if ((r = __mp_addstring(&y->strings, s)) == NULL)
751 {
752 __mp_freeslot(&y->table, n);
753 return 0;
754 }
755 __mp_treeinsert(&y->dtree, &n->data.node, a);
756 n->data.file = i->file;
757 n->data.name = r;
758 n->data.addr = (void *) a;
759 n->data.size = l;
760 n->data.index = 0;
761 n->data.offset = 0;
762 /* Unfortunately, the imagehlp library does not provide information
763 * about the visibility of symbols.
764 */
765 n->data.flags = 0;
766 }
767 return 1;
768 }
769 #endif /* DYNLINK */
770
771
772 #if FORMAT == FORMAT_AOUT
773 /* Allocate a set of symbol nodes for an a.out executable file.
774 */
775
776 static
777 int
addsymbols(symhead * y,char * e,char * l,char * f,size_t b,size_t a)778 addsymbols(symhead *y, char *e, char *l, char *f, size_t b, size_t a)
779 {
780 struct exec *o;
781 struct nlist *p;
782 char *c, *m;
783 size_t i, n;
784
785 /* Check that we have a valid a.out executable file.
786 */
787 if (b < sizeof(struct exec))
788 {
789 c = "not an object file";
790 if (l != NULL)
791 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
792 else
793 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
794 return 1;
795 }
796 o = (struct exec *) e;
797 if (N_BADMAG(*o))
798 {
799 c = "not an executable file";
800 if (l != NULL)
801 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
802 else
803 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
804 return 1;
805 }
806 /* Look for the symbol table.
807 */
808 i = N_SYMOFF(*o);
809 n = o->a_syms;
810 if ((i == 0) || (n == 0) || (b < i + n))
811 {
812 c = "missing symbol table";
813 if (l != NULL)
814 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
815 else
816 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
817 return 1;
818 }
819 p = (struct nlist *) (e + i);
820 b -= i + n;
821 n /= sizeof(struct nlist);
822 /* Look for the string table.
823 */
824 m = e + N_STROFF(*o);
825 if (b < 4)
826 i = 0;
827 else
828 i = *((size_t *) m);
829 if ((i == 0) || (b < i))
830 {
831 c = "missing string table";
832 if (l != NULL)
833 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
834 else
835 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
836 return 1;
837 }
838 if (l != NULL)
839 f = l;
840 /* Cycle through every symbol contained in the executable file.
841 */
842 for (i = 0; i < n; i++, p++)
843 /* We only need to bother looking at text symbols.
844 */
845 if ((((p->n_type & N_TYPE) == N_TEXT) && !(p->n_type & N_STAB)) &&
846 !addsymbol(y, p, f, m + p->n_un.n_strx, a))
847 return 0;
848 return 1;
849 }
850 #elif FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF
851 /* Allocate a set of symbol nodes for a COFF or XCOFF executable file.
852 */
853
854 static
855 int
addsymbols(symhead * y,char * e,char * l,char * f,size_t b,size_t a)856 addsymbols(symhead *y, char *e, char *l, char *f, size_t b, size_t a)
857 {
858 char n[SYMNMLEN + 1];
859 FILHDR *o;
860 AOUTHDR *v;
861 SCNHDR *h;
862 SYMENT *p;
863 char *c, *m, *s;
864 size_t i, t;
865
866 /* Check that we have a valid COFF or XCOFF executable file.
867 */
868 if (b < FILHSZ)
869 {
870 c = "not an object file";
871 if (l != NULL)
872 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
873 else
874 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
875 return 1;
876 }
877 o = (FILHDR *) e;
878 b -= FILHSZ;
879 if (!ISCOFF(o->f_magic) || (o->f_opthdr == 0) || (b < o->f_opthdr))
880 {
881 c = "not an executable file";
882 if (l != NULL)
883 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
884 else
885 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
886 return 1;
887 }
888 /* COFF and XCOFF dynamic linkers don't record the original start
889 * address of the text section so we must adjust the base address here
890 * if necessary.
891 */
892 if ((a != 0) && (o->f_opthdr >= sizeof(AOUTHDR)))
893 {
894 v = (AOUTHDR *) (e + FILHSZ);
895 if (a > v->text_start)
896 a -= (v->text_start & ~0xFFFF);
897 }
898 b -= o->f_opthdr;
899 if ((o->f_nscns == 0) || (b < o->f_nscns * SCNHSZ))
900 {
901 c = "missing section table";
902 if (l != NULL)
903 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
904 else
905 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
906 return 1;
907 }
908 /* Look for the section index of the text section. This is
909 * usually 1, but we should really make sure.
910 */
911 h = (SCNHDR *) (e + FILHSZ + o->f_opthdr);
912 b += FILHSZ + o->f_opthdr - o->f_symptr;
913 for (i = t = 0; i < o->f_nscns; i++)
914 if ((h[i].s_flags & STYP_TEXT) ||
915 (strncmp(h[i].s_name, ".text", 8) == 0))
916 {
917 t = i + 1;
918 break;
919 }
920 if (t == 0)
921 t = 1;
922 /* Look for the symbol table.
923 */
924 i = o->f_nsyms * SYMESZ;
925 if ((o->f_symptr == 0) || (o->f_nsyms == 0) || (b < i))
926 {
927 c = "missing symbol table";
928 if (l != NULL)
929 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
930 else
931 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
932 return 1;
933 }
934 p = (SYMENT *) (e + o->f_symptr);
935 b -= i;
936 /* Look for the string table.
937 */
938 m = (char *) p + i;
939 if (b < 4)
940 i = 0;
941 else
942 i = *((size_t *) m);
943 if ((i == 0) || (b < i))
944 {
945 c = "missing string table";
946 if (l != NULL)
947 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", l, f, c);
948 else
949 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, c);
950 return 1;
951 }
952 if (l != NULL)
953 f = l;
954 /* Cycle through every symbol contained in the executable file.
955 */
956 for (i = 0; i < o->f_nsyms; i += p->n_numaux + 1,
957 p = (SYMENT *) ((char *) p + (p->n_numaux + 1) * SYMESZ))
958 /* We only need to bother looking at text symbols.
959 */
960 if (p->n_scnum == t)
961 {
962 if (p->n_zeroes)
963 {
964 /* Symbol name is stored in structure.
965 */
966 strncpy(n, p->n_name, SYMNMLEN);
967 n[SYMNMLEN] = '\0';
968 s = n;
969 }
970 else
971 /* Symbol name is stored in string table.
972 */
973 s = m + p->n_offset;
974 if (!addsymbol(y, p, f, s, a))
975 return 0;
976 }
977 return 1;
978 }
979 #elif FORMAT == FORMAT_ELF32
980 /* Allocate a set of symbol nodes for an ELF32 object file.
981 */
982
983 static
984 int
addsymbols(symhead * y,Elf * e,char * a,char * f,size_t b)985 addsymbols(symhead *y, Elf *e, char *a, char *f, size_t b)
986 {
987 Elf_Scn *s;
988 Elf32_Shdr *h;
989 Elf32_Sym *p;
990 Elf_Data *d;
991 char *m;
992 size_t i, l, n, t;
993
994 /* Look for the symbol table.
995 */
996 for (s = elf_nextscn(e, NULL), d = NULL; s != NULL; s = elf_nextscn(e, s))
997 if ((h = elf32_getshdr(s)) && (h->sh_type == SHT_SYMTAB) &&
998 (d = elf_getdata(s, NULL)))
999 break;
1000 if (d == NULL)
1001 /* If we couldn't find the symbol table then it is likely that the file
1002 * has been stripped. However, if the file was dynamically linked then
1003 * we may be able to obtain some symbols from its dynamic symbol table.
1004 */
1005 for (s = elf_nextscn(e, NULL), d = NULL; s != NULL;
1006 s = elf_nextscn(e, s))
1007 if ((h = elf32_getshdr(s)) && (h->sh_type == SHT_DYNSYM) &&
1008 (d = elf_getdata(s, NULL)))
1009 break;
1010 if ((d == NULL) || (d->d_buf == NULL) || (d->d_size == 0))
1011 {
1012 m = "missing symbol table";
1013 if (a != NULL)
1014 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1015 else
1016 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1017 return 1;
1018 }
1019 t = h->sh_link;
1020 /* Look for the string table.
1021 */
1022 if (((s = elf_getscn(e, t)) == NULL) || ((h = elf32_getshdr(s)) == NULL) ||
1023 (h->sh_type != SHT_STRTAB))
1024 {
1025 m = "missing string table";
1026 if (a != NULL)
1027 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1028 else
1029 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1030 return 1;
1031 }
1032 if (a != NULL)
1033 f = a;
1034 p = (Elf32_Sym *) d->d_buf + 1;
1035 l = d->d_size / sizeof(Elf32_Sym);
1036 /* Cycle through every symbol contained in the object file.
1037 */
1038 for (i = 1; i < l; i++, p++)
1039 /* We don't need to bother looking at undefined, absolute or common
1040 * symbols, and we only need to store non-data symbols. However, on
1041 * IRIX the section index for a symbol in a linked object file does
1042 * not always refer to the ELF section it was defined in so we skip
1043 * the last check.
1044 */
1045 #if SYSTEM == SYSTEM_IRIX
1046 if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) &&
1047 (n != SHN_COMMON))
1048 #else /* SYSTEM */
1049 if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) &&
1050 (n != SHN_COMMON) && (s = elf_getscn(e, n)) &&
1051 (h = elf32_getshdr(s)) && (h->sh_flags & SHF_EXECINSTR))
1052 #endif /* SYSTEM */
1053 if (!addsymbol(y, p, f, elf_strptr(e, t, p->st_name), b))
1054 return 0;
1055 return 1;
1056 }
1057 #elif FORMAT == FORMAT_ELF64
1058 /* Allocate a set of symbol nodes for an ELF64 object file.
1059 */
1060
1061 static
1062 int
addsymbols(symhead * y,Elf * e,char * a,char * f,size_t b)1063 addsymbols(symhead *y, Elf *e, char *a, char *f, size_t b)
1064 {
1065 Elf_Scn *s;
1066 Elf64_Shdr *h;
1067 Elf64_Sym *p;
1068 Elf_Data *d;
1069 char *m;
1070 size_t i, l, n, t;
1071
1072 /* Look for the symbol table.
1073 */
1074 for (s = elf_nextscn(e, NULL), d = NULL; s != NULL; s = elf_nextscn(e, s))
1075 if ((h = elf64_getshdr(s)) && (h->sh_type == SHT_SYMTAB) &&
1076 (d = elf_getdata(s, NULL)))
1077 break;
1078 if (d == NULL)
1079 /* If we couldn't find the symbol table then it is likely that the file
1080 * has been stripped. However, if the file was dynamically linked then
1081 * we may be able to obtain some symbols from its dynamic symbol table.
1082 */
1083 for (s = elf_nextscn(e, NULL), d = NULL; s != NULL;
1084 s = elf_nextscn(e, s))
1085 if ((h = elf64_getshdr(s)) && (h->sh_type == SHT_DYNSYM) &&
1086 (d = elf_getdata(s, NULL)))
1087 break;
1088 if ((d == NULL) || (d->d_buf == NULL) || (d->d_size == 0))
1089 {
1090 m = "missing symbol table";
1091 if (a != NULL)
1092 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1093 else
1094 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1095 return 1;
1096 }
1097 t = h->sh_link;
1098 /* Look for the string table.
1099 */
1100 if (((s = elf_getscn(e, t)) == NULL) || ((h = elf64_getshdr(s)) == NULL) ||
1101 (h->sh_type != SHT_STRTAB))
1102 {
1103 m = "missing string table";
1104 if (a != NULL)
1105 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1106 else
1107 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1108 return 1;
1109 }
1110 if (a != NULL)
1111 f = a;
1112 p = (Elf64_Sym *) d->d_buf + 1;
1113 l = d->d_size / sizeof(Elf64_Sym);
1114 /* Cycle through every symbol contained in the object file.
1115 */
1116 for (i = 1; i < l; i++, p++)
1117 /* We don't need to bother looking at undefined, absolute or common
1118 * symbols, and we only need to store non-data symbols. However, on
1119 * IRIX the section index for a symbol in a linked object file does
1120 * not always refer to the ELF section it was defined in so we skip
1121 * the last check.
1122 */
1123 #if SYSTEM == SYSTEM_IRIX
1124 if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) &&
1125 (n != SHN_COMMON))
1126 #else /* SYSTEM */
1127 if (((n = p->st_shndx) != SHN_UNDEF) && (n != SHN_ABS) &&
1128 (n != SHN_COMMON) && (s = elf_getscn(e, n)) &&
1129 (h = elf64_getshdr(s)) && (h->sh_flags & SHF_EXECINSTR))
1130 #endif /* SYSTEM */
1131 if (!addsymbol(y, p, f, elf_strptr(e, t, p->st_name), b))
1132 return 0;
1133 return 1;
1134 }
1135 #elif FORMAT == FORMAT_BFD
1136 /* Allocate a set of symbol nodes for a BFD object file.
1137 */
1138
1139 static
1140 int
addsymbols(symhead * y,bfd * h,char * a,char * f,size_t b)1141 addsymbols(symhead *y, bfd *h, char *a, char *f, size_t b)
1142 {
1143 asymbol **p;
1144 char *m;
1145 long i, n;
1146 int d, r;
1147
1148 /* Look for the symbol table.
1149 */
1150 d = 0;
1151 if ((n = bfd_get_symtab_upper_bound(h)) < 0)
1152 {
1153 m = (char *) bfd_errmsg(bfd_get_error());
1154 if (a != NULL)
1155 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1156 else
1157 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1158 return 0;
1159 }
1160 if (n == 0)
1161 {
1162 /* If we couldn't find the symbol table then it is likely that the file
1163 * has been stripped. However, if the file was dynamically linked then
1164 * we may be able to obtain some symbols from its dynamic symbol table.
1165 */
1166 if ((n = bfd_get_dynamic_symtab_upper_bound(h)) < 0)
1167 {
1168 m = (char *) bfd_errmsg(bfd_get_error());
1169 if (a != NULL)
1170 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1171 else
1172 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1173 return 0;
1174 }
1175 if (n == 0)
1176 {
1177 m = "missing symbol table";
1178 if (a != NULL)
1179 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1180 else
1181 __mp_warn(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1182 return 1;
1183 }
1184 d = 1;
1185 }
1186 /* It's actually safe to call malloc() here since the library checks
1187 * for recursive behaviour.
1188 */
1189 if ((p = (asymbol **) malloc(n)) == NULL)
1190 {
1191 m = "no memory for symbols";
1192 if (a != NULL)
1193 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1194 else
1195 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1196 return 0;
1197 }
1198 r = 1;
1199 if (((d == 0) && ((n = bfd_canonicalize_symtab(h, p)) < 0)) ||
1200 ((d == 1) && ((n = bfd_canonicalize_dynamic_symtab(h, p)) < 0)))
1201 {
1202 m = (char *) bfd_errmsg(bfd_get_error());
1203 if (a != NULL)
1204 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", a, f, m);
1205 else
1206 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", f, m);
1207 r = 0;
1208 }
1209 else
1210 {
1211 /* Cycle through every symbol contained in the object file.
1212 */
1213 if (a != NULL)
1214 f = a;
1215 for (i = 0; i < n; i++)
1216 /* We don't need to bother looking at undefined, absolute or common
1217 * symbols, and we only need to store non-data symbols.
1218 */
1219 if (!bfd_is_und_section(p[i]->section) &&
1220 !bfd_is_abs_section(p[i]->section) &&
1221 !bfd_is_com_section(p[i]->section) &&
1222 (p[i]->section->flags & SEC_CODE))
1223 if (!addsymbol(y, p[i], f, (char *) p[i]->name,
1224 (size_t) p[i]->section->vma + b))
1225 {
1226 r = 0;
1227 break;
1228 }
1229 }
1230 /* If we are making use of line number information in the object files then
1231 * we store the symbol table along with the access library handle; otherwise
1232 * we can free the symbol table now.
1233 */
1234 if (y->lineinfo && (r == 1))
1235 ((objectfile *) y->htail)->symbols = p;
1236 else
1237 free(p);
1238 return r;
1239 }
1240 #endif /* FORMAT */
1241
1242
1243 #if DYNLINK == DYNLINK_WINDOWS
1244 /* The callback function called to allocate a set of symbol nodes for each
1245 * module located by the imagehlp library.
1246 */
1247
1248 static
1249 int __stdcall
addsyms(char * f,unsigned long b,void * p)1250 addsyms(char *f, unsigned long b, void *p)
1251 {
1252 modinfo *i;
1253 symhead *y;
1254 char *t;
1255 syminfo s;
1256 IMAGEHLP_MODULE m;
1257 size_t l;
1258 int r;
1259
1260 r = 1;
1261 i = (modinfo *) p;
1262 y = i->syms;
1263 l = y->dtree.size;
1264 /* The executable file is the first module, so we only want to examine it
1265 * if we are not looking for external symbols. The DLLs are the subsequent
1266 * modules, so we only want to examine them if we are looking for external
1267 * symbols.
1268 */
1269 if ((!i->libs && !i->index) || (i->libs && i->index))
1270 {
1271 /* Attempt to determine the full path of the current module.
1272 */
1273 m.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
1274 if (SymGetModuleInfo(GetCurrentProcess(), b, &m))
1275 f = m.LoadedImageName;
1276 if ((t = __mp_addstring(&y->strings, f)) == NULL)
1277 r = 0;
1278 else
1279 {
1280 /* Cycle through every symbol contained in the module.
1281 */
1282 s.syms = y;
1283 s.file = t;
1284 r = SymEnumerateSymbols(GetCurrentProcess(), b, addsym, &s);
1285 }
1286 if (i->libs)
1287 {
1288 if (r == 1)
1289 {
1290 l = y->dtree.size - l;
1291 __mp_diag("read %lu symbol%s from ", l, (l == 1) ? "" : "s");
1292 }
1293 else
1294 __mp_diag("problem reading symbols from ");
1295 if (__mp_diagflags & FLG_HTML)
1296 __mp_diagtag("<TT>");
1297 __mp_diag("%s", f);
1298 if (__mp_diagflags & FLG_HTML)
1299 {
1300 __mp_diagtag("</TT>\n");
1301 __mp_diagtag("<BR>");
1302 }
1303 __mp_diag("\n");
1304 }
1305 }
1306 i->index++;
1307 return r;
1308 }
1309 #endif /* DYNLINK */
1310
1311
1312 /* Read a file and add all relevant symbols contained within it to the
1313 * symbol table.
1314 */
1315
1316 MP_GLOBAL
1317 int
__mp_addsymbols(symhead * y,char * s,char * v,size_t b)1318 __mp_addsymbols(symhead *y, char *s, char *v, size_t b)
1319 {
1320 #if FORMAT == FORMAT_AOUT || FORMAT == FORMAT_COFF || \
1321 FORMAT == FORMAT_XCOFF || FORMAT == FORMAT_ELF32 || \
1322 FORMAT == FORMAT_ELF64 || FORMAT == FORMAT_BFD
1323 #if FORMAT == FORMAT_AOUT || (SYSTEM == SYSTEM_LYNXOS && \
1324 (FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF))
1325 char *m;
1326 off_t o;
1327 int f;
1328 #elif FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF
1329 LDFILE *f;
1330 char *c, *m, *n;
1331 ARCHDR a;
1332 size_t o;
1333 #elif FORMAT == FORMAT_ELF32 || FORMAT == FORMAT_ELF64
1334 Elf *a, *e;
1335 Elf_Arhdr *h;
1336 int f;
1337 #elif FORMAT == FORMAT_BFD
1338 objectfile *p, *q;
1339 bfd *a, *g, *h;
1340 #endif /* FORMAT */
1341 char *t;
1342 #elif FORMAT == FORMAT_PE
1343 modinfo m;
1344 #endif /* FORMAT */
1345 size_t l;
1346 int r;
1347
1348 r = 1;
1349 l = y->dtree.size;
1350 #if FORMAT == FORMAT_AOUT || (SYSTEM == SYSTEM_LYNXOS && \
1351 (FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF))
1352 /* This is a very simple, yet portable, way to read symbols from a.out
1353 * executable files, or from COFF or XCOFF executable files when libld
1354 * is not available.
1355 */
1356 if ((f = open(s, O_RDONLY)) == -1)
1357 {
1358 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: cannot open file\n", s);
1359 r = 0;
1360 }
1361 else
1362 {
1363 /* Find out the size of the file by doing a seek to the end of the file
1364 * and then a seek back to the start of the file. Unfortunately, on
1365 * some systems off_t is a structure, so the code below may not work
1366 * for them.
1367 */
1368 if (((o = lseek(f, 0, SEEK_END)) == (off_t) -1) ||
1369 (lseek(f, 0, SEEK_SET) == (off_t) -1))
1370 {
1371 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: cannot seek file\n", s);
1372 r = 0;
1373 }
1374 else if ((m = (char *) malloc((size_t) o)) == NULL)
1375 {
1376 /* It's actually safe to call malloc() here since the library
1377 * checks for recursive behaviour.
1378 */
1379 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: no memory for symbols\n",
1380 s);
1381 r = 0;
1382 }
1383 else
1384 {
1385 if (read(f, m, (size_t) o) != (size_t) o)
1386 {
1387 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: cannot read file\n",
1388 s);
1389 r = 0;
1390 }
1391 else if ((t = __mp_addstring(&y->strings, s)) == NULL)
1392 r = 0;
1393 else
1394 r = addsymbols(y, m, NULL, t, (size_t) o, b);
1395 free(m);
1396 }
1397 close(f);
1398 }
1399 #elif FORMAT == FORMAT_COFF || FORMAT == FORMAT_XCOFF
1400 /* We use the libld COFF and XCOFF access library in order to simplify
1401 * the reading of symbols. If this library is not available on a certain
1402 * platform then use the above code for reading a.out files and comment
1403 * this code out. However, a better solution would be to use the GNU
1404 * BFD library if it is available.
1405 */
1406 t = NULL;
1407 if ((f = ldopen(s, NULL)) == NULL)
1408 {
1409 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: cannot open file\n", s);
1410 r = 0;
1411 }
1412 while (r == 1)
1413 {
1414 if (ldahread(f, &a))
1415 {
1416 n = a.ar_name;
1417 o = a.ar_size;
1418 if (((v != NULL) && (strcmp(n, v) != 0)) ||
1419 (FSEEK(f, 0, BEGINNING) == -1))
1420 {
1421 if (ldclose(f))
1422 break;
1423 if ((f = ldopen(s, f)) == NULL)
1424 r = 0;
1425 continue;
1426 }
1427 }
1428 else
1429 n = NULL;
1430 /* Find out the size of the file by doing a seek to the end of the file
1431 * and then a seek back to the start of the file, but only if this is
1432 * not an archive member.
1433 */
1434 if ((n == NULL) && ((FSEEK(f, 0, END) == -1) ||
1435 ((o = FTELL(f)) == (size_t) -1) || (FSEEK(f, 0, BEGINNING) == -1)))
1436 {
1437 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: cannot seek file\n", s);
1438 r = 0;
1439 }
1440 else if ((m = (char *) malloc(o)) == NULL)
1441 {
1442 /* It's actually safe to call malloc() here since the library
1443 * checks for recursive behaviour.
1444 */
1445 c = "no memory for symbols";
1446 if (n != NULL)
1447 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", s, n, c);
1448 else
1449 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", s, c);
1450 r = 0;
1451 }
1452 else
1453 {
1454 if (FREAD(m, sizeof(char), o, f) != o)
1455 {
1456 c = "cannot read file";
1457 if (n != NULL)
1458 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", s, n,
1459 c);
1460 else
1461 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", s, c);
1462 r = 0;
1463 }
1464 else if ((t == NULL) &&
1465 ((t = __mp_addstring(&y->strings, s)) == NULL))
1466 r = 0;
1467 else if (n != NULL)
1468 r = addsymbols(y, m, t, n, o, b);
1469 else
1470 r = addsymbols(y, m, NULL, t, o, b);
1471 free(m);
1472 }
1473 if (ldclose(f))
1474 break;
1475 if ((r == 1) && ((f = ldopen(s, f)) == NULL))
1476 r = 0;
1477 }
1478 #elif FORMAT == FORMAT_ELF32 || FORMAT == FORMAT_ELF64
1479 /* We use the libelf ELF access library in order to simplify the reading
1480 * of symbols. At the moment, this solution is better than using the
1481 * GNU BFD library as it currently has no support for symbol sizes or
1482 * liaising with the dynamic linker.
1483 */
1484 if (elf_version(EV_CURRENT) == EV_NONE)
1485 {
1486 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: wrong version of libelf\n", s);
1487 r = 0;
1488 }
1489 else if ((f = open(s, O_RDONLY)) == -1)
1490 {
1491 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: cannot open file\n", s);
1492 r = 0;
1493 }
1494 else
1495 {
1496 if ((e = elf_begin(f, ELF_C_READ, NULL)) == NULL)
1497 {
1498 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", s, elf_errmsg(-1));
1499 r = 0;
1500 }
1501 else if ((t = __mp_addstring(&y->strings, s)) == NULL)
1502 r = 0;
1503 else
1504 {
1505 if (elf_kind(e) == ELF_K_AR)
1506 /* Normally we wouldn't ever need to read symbols from an
1507 * archive library, but this is just provided for
1508 * completeness.
1509 */
1510 while ((r == 1) && (a = elf_begin(f, ELF_C_READ, e)))
1511 {
1512 if ((h = elf_getarhdr(a)) == NULL)
1513 {
1514 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", s,
1515 elf_errmsg(-1));
1516 r = 0;
1517 }
1518 else if ((*h->ar_name != '/') && ((v == NULL) ||
1519 (strcmp(h->ar_name, v) == 0)))
1520 r = addsymbols(y, a, t, h->ar_name, b);
1521 if (r == 1)
1522 elf_next(a);
1523 elf_end(a);
1524 }
1525 else
1526 r = addsymbols(y, e, NULL, t, b);
1527 elf_end(e);
1528 }
1529 close(f);
1530 }
1531 #elif FORMAT == FORMAT_BFD
1532 /* Using the GNU BFD library allows us to read weird and wonderful file
1533 * formats that would otherwise be hard to support. This is probably a
1534 * better choice to use than the in-built a.out, COFF and XCOFF
1535 * implementations but currently has no support for symbol sizes, so the
1536 * ELF access library is still worth using for ELF file formats, but the
1537 * BFD library comes with support for debugging information. So take
1538 * your pick!
1539 */
1540 t = NULL;
1541 bfd_init();
1542 if ((h = bfd_openr(s, NULL)) == NULL)
1543 {
1544 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", s,
1545 bfd_errmsg(bfd_get_error()));
1546 r = 0;
1547 }
1548 else
1549 {
1550 /* Normally we wouldn't ever need to read symbols from an archive
1551 * library, but this is just provided for completeness, and for AIX
1552 * where shared libraries can be embedded within archive libraries.
1553 */
1554 if (bfd_check_format(h, bfd_archive))
1555 {
1556 a = h;
1557 h = bfd_openr_next_archived_file(a, NULL);
1558 }
1559 else
1560 a = NULL;
1561 while (h != NULL)
1562 {
1563 p = NULL;
1564 if ((a != NULL) && (v != NULL) && (strcmp(h->filename, v) != 0))
1565 {
1566 g = h;
1567 h = bfd_openr_next_archived_file(a, g);
1568 bfd_close(g);
1569 continue;
1570 }
1571 if (!bfd_check_format(h, bfd_object))
1572 {
1573 if (a != NULL)
1574 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s [%s]: %s\n", s,
1575 h->filename, bfd_errmsg(bfd_get_error()));
1576 else
1577 __mp_error(ET_MAX, AT_MAX, NULL, 0, "%s: %s\n", s,
1578 bfd_errmsg(bfd_get_error()));
1579 r = 0;
1580 }
1581 else if (y->lineinfo &&
1582 ((p = (objectfile *) malloc(sizeof(objectfile))) == NULL))
1583 r = 0;
1584 else if ((t == NULL) &&
1585 ((t = __mp_addstring(&y->strings, s)) == NULL))
1586 r = 0;
1587 else
1588 {
1589 if (y->lineinfo)
1590 {
1591 if (y->hhead == NULL)
1592 y->hhead = p;
1593 else
1594 {
1595 q = (objectfile *) y->htail;
1596 q->next = p;
1597 }
1598 y->htail = p;
1599 p->next = NULL;
1600 p->file = h;
1601 p->symbols = NULL;
1602 p->base = b;
1603 }
1604 if (a != NULL)
1605 r = addsymbols(y, h, t, (char *) h->filename, b);
1606 else
1607 r = addsymbols(y, h, NULL, t, b);
1608 if (y->lineinfo && (r == 0))
1609 if (y->hhead == p)
1610 y->hhead = y->htail = NULL;
1611 else
1612 {
1613 y->htail = q;
1614 q->next = NULL;
1615 }
1616 }
1617 g = h;
1618 if ((a != NULL) && (r == 1))
1619 h = bfd_openr_next_archived_file(a, g);
1620 else
1621 h = NULL;
1622 if (!y->lineinfo || (r == 0))
1623 {
1624 if (p != NULL)
1625 free(p);
1626 bfd_close(g);
1627 }
1628 }
1629 if (a != NULL)
1630 bfd_close(a);
1631 }
1632 #elif FORMAT == FORMAT_PE
1633 /* We only want to obtain the symbols from the executable file using the
1634 * imagehlp library if we are not using another object file access library,
1635 * such as GNU BFD.
1636 */
1637 m.syms = y;
1638 m.index = 0;
1639 m.libs = 0;
1640 r = SymEnumerateModules(GetCurrentProcess(), addsyms, &m);
1641 #endif /* FORMAT */
1642 if (r == 1)
1643 {
1644 l = y->dtree.size - l;
1645 __mp_diag("read %lu symbol%s from ", l, (l == 1) ? "" : "s");
1646 }
1647 else
1648 __mp_diag("problem reading symbols from ");
1649 if (__mp_diagflags & FLG_HTML)
1650 __mp_diagtag("<TT>");
1651 __mp_diag("%s", s);
1652 if (__mp_diagflags & FLG_HTML)
1653 __mp_diagtag("</TT>");
1654 if (v != NULL)
1655 if (__mp_diagflags & FLG_HTML)
1656 {
1657 __mp_diag(" [");
1658 __mp_diagtag("<TT>");
1659 __mp_diag("%s", v);
1660 __mp_diagtag("</TT>");
1661 __mp_diag("]");
1662 }
1663 else
1664 __mp_diag(" [%s]", v);
1665 __mp_diag("\n");
1666 if (__mp_diagflags & FLG_HTML)
1667 __mp_diagtag("<BR>\n");
1668 return r;
1669 }
1670
1671
1672 /* Add any external or additional symbols to the symbol table.
1673 */
1674
1675 MP_GLOBAL
1676 int
__mp_addextsymbols(symhead * y,meminfo * e)1677 __mp_addextsymbols(symhead *y, meminfo *e)
1678 {
1679 #if DYNLINK == DYNLINK_AIX
1680 static char b[4096];
1681 struct ld_info *l;
1682 char *s;
1683 #elif DYNLINK == DYNLINK_BSD
1684 #if SYSTEM == SYSTEM_SUNOS
1685 struct link_dynamic *d;
1686 struct link_map *l;
1687 #else /* SYSTEM */
1688 struct _dynamic *d;
1689 struct so_map *l;
1690 #endif /* SYSTEM */
1691 #elif DYNLINK == DYNLINK_HPUX
1692 struct shl_descriptor d;
1693 size_t i;
1694 unsigned int o;
1695 #elif DYNLINK == DYNLINK_IRIX
1696 struct obj_list *l;
1697 struct obj *o;
1698 objectinfo *i;
1699 char *s;
1700 size_t b;
1701 #elif DYNLINK == DYNLINK_OSF
1702 ldr_region_info_t r;
1703 ldr_module_info_t i;
1704 ldr_module_t m;
1705 ldr_process_t p;
1706 size_t c, l, n;
1707 size_t b;
1708 #elif DYNLINK == DYNLINK_SVR4
1709 #if ENVIRON == ENVIRON_64
1710 Elf64_Dyn *d;
1711 #else /* ENVIRON */
1712 Elf32_Dyn *d;
1713 #endif /* ENVIRON */
1714 dynamiclink *l;
1715 #elif DYNLINK == DYNLINK_WINDOWS
1716 modinfo m;
1717 #endif /* DYNLINK */
1718
1719 /* This function liaises with the dynamic linker when a program is
1720 * dynamically linked in order to read symbols from any required shared
1721 * objects.
1722 */
1723 #if DYNLINK == DYNLINK_AIX
1724 if (loadquery(L_GETINFO, b, sizeof(b)) != -1)
1725 {
1726 /* We skip past the first item on the list since it represents the
1727 * executable file, but we may wish to record the name of the file
1728 * if we haven't already determined it.
1729 */
1730 l = (struct ld_info *) b;
1731 s = l->ldinfo_filename;
1732 if ((e->prog == NULL) && (*s != '\0'))
1733 e->prog = __mp_addstring(&y->strings, s);
1734 while (l = l->ldinfo_next ? (struct ld_info *)
1735 ((char *) l + l->ldinfo_next) : NULL)
1736 if (*l->ldinfo_filename != '\0')
1737 {
1738 /* If the filename represents an archive file then the member
1739 * name within the archive will follow immediately after it.
1740 */
1741 s = l->ldinfo_filename + strlen(l->ldinfo_filename) + 1;
1742 if (*s == '\0')
1743 s = NULL;
1744 if (!__mp_addsymbols(y, l->ldinfo_filename, s,
1745 (unsigned long) l->ldinfo_textorg))
1746 return 0;
1747 }
1748 }
1749 #elif DYNLINK == DYNLINK_BSD
1750 /* Check to see if the dynamic linker has set up the _DYNAMIC symbol
1751 * and also check that it is a valid structure.
1752 */
1753 if ((d = &_DYNAMIC) &&
1754 #if SYSTEM == SYSTEM_SUNOS
1755 (d->ld_version > 1) && (d->ld_version <= 3) && (d->ld_un.ld_1 != NULL))
1756 #else /* SYSTEM */
1757 (d->d_version == LD_VERSION_BSD) && (d->d_un.d_sdt != NULL))
1758 #endif /* SYSTEM */
1759 {
1760 #if SYSTEM == SYSTEM_SUNOS
1761 l = d->ld_un.ld_1->ld_loaded;
1762 #else /* SYSTEM */
1763 l = d->d_un.d_sdt->sdt_loaded;
1764 #endif /* SYSTEM */
1765 while (l != NULL)
1766 {
1767 #if SYSTEM == SYSTEM_SUNOS
1768 if ((l->lm_name != NULL) && (*l->lm_name != '\0') &&
1769 !__mp_addsymbols(y, l->lm_name, NULL, l->lm_addr))
1770 #else /* SYSTEM */
1771 if ((l->som_path != NULL) && (*l->som_path != '\0') &&
1772 !__mp_addsymbols(y, l->som_path, NULL, l->som_addr))
1773 #endif /* SYSTEM */
1774 return 0;
1775 #if SYSTEM == SYSTEM_SUNOS
1776 l = l->lm_next;
1777 #else /* SYSTEM */
1778 l = l->som_next;
1779 #endif /* SYSTEM */
1780 }
1781 }
1782 #elif DYNLINK == DYNLINK_HPUX
1783 /* An index of -1 indicates the dynamic linker and an index of 0 indicates
1784 * the main executable program. We are interested in all other object files
1785 * that the program depends on, but we may wish to record the name of the
1786 * executable file if we haven't already determined it.
1787 */
1788 if ((e->prog == NULL) && (shl_get_r(0, &d) != -1) &&
1789 (d.filename[0] != '\0'))
1790 e->prog = __mp_addstring(&y->strings, d.filename);
1791 for (i = 1; shl_get_r(i, &d) != -1; i++)
1792 {
1793 /* Determine the offset of the first text symbol in the library. This
1794 * is normally 0x1000 but may be something else on later systems. The
1795 * handle structure is not documented anywhere, but the fourth word
1796 * appears to contain the information we need, based on trial and error.
1797 */
1798 if (d.handle != NULL)
1799 o = ((unsigned int *) d.handle)[3];
1800 else
1801 o = 0;
1802 if ((d.filename[0] != '\0') &&
1803 !__mp_addsymbols(y, d.filename, NULL, d.tstart - o))
1804 return 0;
1805 }
1806 #elif DYNLINK == DYNLINK_IRIX
1807 if (l = __rld_obj_head)
1808 /* Determine if the shared object list we are looking at contains O32
1809 * ABI object files or N32 ABI object files.
1810 */
1811 if (l->data == 0xFFFFFFFF)
1812 {
1813 /* We skip past the first item on the list since it represents the
1814 * executable file, but we may wish to record the name of the file
1815 * if we haven't already determined it.
1816 */
1817 i = (objectinfo *) l;
1818 s = (char *) i->name;
1819 if ((e->prog == NULL) && (s != NULL) && (*s != '\0'))
1820 e->prog = __mp_addstring(&y->strings, s);
1821 while (i = (objectinfo *) i->next)
1822 {
1823 s = (char *) i->name;
1824 b = (long) i->ehdr - (long) i->ohdr;
1825 if ((s != NULL) && (*s != '\0') &&
1826 !__mp_addsymbols(y, s, NULL, b))
1827 return 0;
1828 }
1829 }
1830 else
1831 {
1832 /* We skip past the first item on the list since it represents the
1833 * executable file, but we may wish to record the name of the file
1834 * if we haven't already determined it.
1835 */
1836 o = (struct obj *) l->data;
1837 s = o->o_path;
1838 if ((e->prog == NULL) && (s != NULL) && (*s != '\0'))
1839 e->prog = __mp_addstring(&y->strings, s);
1840 while (l = l->next)
1841 {
1842 o = (struct obj *) l->data;
1843 s = o->o_path;
1844 b = (long) o->o_text_start - (long) o->o_base_address;
1845 if ((s != NULL) && (*s != '\0') &&
1846 !__mp_addsymbols(y, s, NULL, b))
1847 return 0;
1848 }
1849 }
1850 #elif DYNLINK == DYNLINK_OSF
1851 c = 0;
1852 p = ldr_my_process();
1853 m = LDR_NULL_MODULE;
1854 while ((ldr_next_module(p, &m) == 0) && (m != LDR_NULL_MODULE))
1855 if (ldr_inq_module(p, m, &i, sizeof(i), &l) == 0)
1856 {
1857 /* We skip past the first item on the list since it represents the
1858 * executable file, but we may wish to record the name of the file
1859 * if we haven't already determined it.
1860 */
1861 if (c++ == 0)
1862 {
1863 if ((e->prog == NULL) && (i.lmi_name[0] != '\0'))
1864 e->prog = __mp_addstring(&y->strings, i.lmi_name);
1865 continue;
1866 }
1867 for (n = 0; n < (size_t) i.lmi_nregion; n++)
1868 if ((ldr_inq_region(p, m, (ldr_region_t) n, &r, sizeof(r),
1869 &l) == 0) && (strcmp(r.lri_name, ".text") == 0))
1870 {
1871 b = (long) r.lri_mapaddr - (long) r.lri_vaddr;
1872 if ((i.lmi_name[0] != '\0') && !__mp_addsymbols(y,
1873 i.lmi_name, NULL, b))
1874 return 0;
1875 break;
1876 }
1877 }
1878 #elif DYNLINK == DYNLINK_SVR4
1879 #if ENVIRON == ENVIRON_64
1880 if ((&_DYNAMIC != NULL) && (d = (Elf64_Dyn *) _DYNAMIC))
1881 #else /* ENVIRON */
1882 if ((&_DYNAMIC != NULL) && (d = (Elf32_Dyn *) _DYNAMIC))
1883 #endif /* ENVIRON */
1884 {
1885 /* Search for the DT_DEBUG tag in the _DYNAMIC symbol.
1886 */
1887 for (l = NULL; d->d_tag != DT_NULL; d++)
1888 if (d->d_tag == DT_DEBUG)
1889 {
1890 if (!d->d_un.d_ptr)
1891 l = NULL;
1892 else
1893 l = (dynamiclink *) *((unsigned long *) d->d_un.d_ptr + 1);
1894 break;
1895 }
1896 /* We skip past the first item on the list since it represents the
1897 * executable file, but we may wish to record the name of the file
1898 * if we haven't already determined it.
1899 */
1900 if (l != NULL)
1901 {
1902 if ((e->prog == NULL) && (l->name != NULL) && (*l->name != '\0'))
1903 e->prog = __mp_addstring(&y->strings, l->name);
1904 l = l->next;
1905 }
1906 while (l != NULL)
1907 {
1908 if ((l->name != NULL) && (*l->name != '\0') &&
1909 !__mp_addsymbols(y, l->name, NULL, l->base))
1910 return 0;
1911 l = l->next;
1912 }
1913 }
1914 #elif DYNLINK == DYNLINK_WINDOWS
1915 /* We always want to initialise the imagehlp library here since we will
1916 * be using it to obtain the symbols from any loaded DLLs here and
1917 * possibly also from the executable file if we are not using any other
1918 * object file access library. In any case we can set the demangling
1919 * option in the imagehlp library and also instruct it to load line number
1920 * information if the USEDEBUG option is given.
1921 */
1922 if (y->lineinfo)
1923 SymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
1924 else
1925 SymSetOptions(SYMOPT_UNDNAME);
1926 SymInitialize(GetCurrentProcess(), NULL, 1);
1927 /* The imagehlp library allows us to locate the symbols contained in
1928 * all of the loaded DLLs without having to actually read the files
1929 * themselves.
1930 */
1931 m.syms = y;
1932 m.index = 0;
1933 m.libs = 1;
1934 if (!SymEnumerateModules(GetCurrentProcess(), addsyms, &m))
1935 return 0;
1936 #endif /* DYNLINK */
1937 return 1;
1938 }
1939
1940
1941 /* Attempt to tidy up the symbol table by correcting any potential errors or
1942 * conflicts from the symbols that have been read.
1943 */
1944
1945 MP_GLOBAL
1946 void
__mp_fixsymbols(symhead * y)1947 __mp_fixsymbols(symhead *y)
1948 {
1949 symnode *n, *p;
1950 void *l, *m;
1951 #if TARGET == TARGET_AMIGA
1952 unsigned long o;
1953 #endif /* TARGET */
1954
1955 #if TARGET == TARGET_AMIGA
1956 o = 0;
1957 #endif /* TARGET */
1958 l = NULL;
1959 for (n = (symnode *) __mp_minimum(y->dtree.root); n != NULL; n = p)
1960 {
1961 /* If a symbol has a zero size and it is closely followed by another
1962 * symbol then the likelihood is that the symbol really has a non-zero
1963 * size so we fix that here. This commonly occurs with system startup
1964 * files.
1965 */
1966 p = (symnode *) __mp_successor(&n->data.node);
1967 if ((n->data.size == 0) && (n->data.addr >= l))
1968 if ((p == NULL) || (n->data.file != p->data.file))
1969 n->data.size = 256;
1970 else
1971 n->data.size = (char *) p->data.addr - (char *) n->data.addr;
1972 if ((m = (char *) n->data.addr + n->data.size) > l)
1973 l = m;
1974 #if TARGET == TARGET_AMIGA
1975 /* On AmigaOS, sections are scatter-loaded into memory and will occupy
1976 * different addresses each time a program is loaded. One easy way to
1977 * determine the run-time address of each function is to find the
1978 * offset for one function and add it to all functions, but this means
1979 * that this function must be compiled with symbolic information and
1980 * assumes that all text symbols are in the one hunk.
1981 */
1982 if ((o == 0) && (strcmp(n->data.name, "___mp_fixsymbols") == 0))
1983 o = (char *) __mp_fixsymbols - (char *) n->data.addr;
1984 #endif /* TARGET */
1985 }
1986 #if TARGET == TARGET_AMIGA
1987 if (o != 0)
1988 {
1989 #if FORMAT == FORMAT_BFD
1990 if (y->hhead != NULL)
1991 ((objectfile *) y->hhead)->base = o;
1992 #endif /* FORMAT */
1993 for (n = (symnode *) __mp_minimum(y->dtree.root); n != NULL;
1994 n = (symnode *) __mp_successor(&n->index.node))
1995 {
1996 n->data.node.key += o;
1997 n->data.addr = (char *) n->data.addr + o;
1998 }
1999 }
2000 #endif /* TARGET */
2001 }
2002
2003
2004 /* Protect the memory blocks used by the symbol table with the supplied access
2005 * permission.
2006 */
2007
2008 MP_GLOBAL
2009 int
__mp_protectsymbols(symhead * y,memaccess a)2010 __mp_protectsymbols(symhead *y, memaccess a)
2011 {
2012 symnode *n;
2013
2014 /* The library already knows what its protection status is so we don't
2015 * need to do anything if the request has already been done.
2016 */
2017 if (y->prot == a)
2018 {
2019 y->protrecur++;
2020 return 1;
2021 }
2022 else if (y->protrecur > 0)
2023 {
2024 y->protrecur--;
2025 return 1;
2026 }
2027 y->prot = a;
2028 for (n = (symnode *) __mp_minimum(y->itree.root); n != NULL;
2029 n = (symnode *) __mp_successor(&n->index.node))
2030 if (!__mp_memprotect(&y->heap->memory, n->index.block, n->index.size,
2031 a))
2032 return 0;
2033 return 1;
2034 }
2035
2036
2037 /* Attempt to find the symbol located at a particular address.
2038 */
2039
2040 MP_GLOBAL
2041 symnode *
__mp_findsymbol(symhead * y,void * p)2042 __mp_findsymbol(symhead *y, void *p)
2043 {
2044 symnode *m, *n, *r;
2045
2046 /* This function does not deal completely correctly with nested symbols
2047 * but that occurrence does not happen frequently so the current
2048 * implementation should suffice.
2049 */
2050 r = NULL;
2051 if (n = (symnode *) __mp_searchlower(y->dtree.root, (unsigned long) p))
2052 {
2053 while ((m = (symnode *) __mp_predecessor(&n->data.node)) &&
2054 (m->data.addr == n->data.addr))
2055 n = m;
2056 for (m = n; (n != NULL) && (n->data.addr == m->data.addr);
2057 n = (symnode *) __mp_successor(&n->data.node))
2058 if ((char *) n->data.addr + n->data.size > (char *) p)
2059 {
2060 #if FORMAT == FORMAT_AOUT
2061 /* We give precedence to global symbols, then local symbols.
2062 */
2063 if ((r == NULL) || (!(r->data.flags & N_EXT) &&
2064 (n->data.flags & N_EXT)))
2065 r = n;
2066 #elif FORMAT == FORMAT_COFF
2067 /* We give precedence to global symbols, then local symbols.
2068 */
2069 if ((r == NULL) || ((r->data.flags == C_STAT) &&
2070 (n->data.flags == C_EXT)))
2071 r = n;
2072 #elif FORMAT == FORMAT_XCOFF
2073 /* We give precedence to global symbols, then hidden external
2074 * symbols, then local symbols.
2075 */
2076 if ((r == NULL) || ((r->data.flags & C_STAT) &&
2077 ((n->data.flags & C_HIDEXT) || (n->data.flags & C_EXT))) ||
2078 ((r->data.flags & C_HIDEXT) && (n->data.flags & C_EXT)))
2079 r = n;
2080 #elif FORMAT == FORMAT_ELF32 || FORMAT == FORMAT_ELF64
2081 /* We give precedence to global symbols, then weak symbols,
2082 * then local symbols.
2083 */
2084 if ((r == NULL) || ((r->data.flags == STB_LOCAL) &&
2085 ((n->data.flags == STB_WEAK) ||
2086 (n->data.flags == STB_GLOBAL))) ||
2087 ((r->data.flags == STB_WEAK) &&
2088 (n->data.flags == STB_GLOBAL)))
2089 r = n;
2090 #elif FORMAT == FORMAT_BFD
2091 /* We give precedence to global symbols, then weak symbols,
2092 * then local symbols.
2093 */
2094 if ((r == NULL) || ((r->data.flags & BSF_LOCAL) &&
2095 ((n->data.flags & BSF_WEAK) ||
2096 (n->data.flags & BSF_GLOBAL))) ||
2097 ((r->data.flags & BSF_WEAK) &&
2098 (n->data.flags & BSF_GLOBAL)))
2099 r = n;
2100 #else /* FORMAT */
2101 r = n;
2102 break;
2103 #endif /* FORMAT */
2104 }
2105 }
2106 return r;
2107 }
2108
2109
2110 #if FORMAT == FORMAT_BFD
2111 /* Search a BFD section for a specific virtual memory address and attempt
2112 * to match it up with source position information.
2113 */
2114
2115 static
2116 void
findsource(bfd * h,asection * p,void * d)2117 findsource(bfd *h, asection *p, void *d)
2118 {
2119 sourcepos *s;
2120 bfd_vma v;
2121 size_t l;
2122
2123 s = (sourcepos *) d;
2124 if (!s->found && !bfd_is_und_section(p) &&
2125 !bfd_is_abs_section(p) && !bfd_is_com_section(p) &&
2126 (p->flags & SEC_ALLOC) && (p->flags & SEC_CODE))
2127 {
2128 v = bfd_section_vma(h, p) + s->base;
2129 l = bfd_section_size(h, p);
2130 if ((s->addr >= v) && (s->addr < v + l))
2131 {
2132 s->file = s->func = NULL;
2133 s->line = 0;
2134 s->found = bfd_find_nearest_line(h, p, s->symbols, s->addr - v,
2135 (const char **) &s->file,
2136 (const char **) &s->func,
2137 &s->line);
2138 }
2139 }
2140 }
2141 #endif /* FORMAT */
2142
2143
2144 /* Attempt to find the source correspondence for a machine instruction located
2145 * at a particular address.
2146 */
2147
2148 MP_GLOBAL
2149 int
__mp_findsource(symhead * y,void * p,char ** s,char ** t,unsigned long * u)2150 __mp_findsource(symhead *y, void *p, char **s, char **t, unsigned long *u)
2151 {
2152 #if FORMAT == FORMAT_BFD
2153 objectfile *n;
2154 sourcepos m;
2155 #endif /* FORMAT */
2156 #if DYNLINK == DYNLINK_WINDOWS
2157 static char b[1024];
2158 IMAGEHLP_SYMBOL *i;
2159 IMAGEHLP_LINE l;
2160 unsigned long d;
2161 #endif /* DYNLINK */
2162
2163 #if FORMAT == FORMAT_BFD
2164 m.addr = (bfd_vma) p;
2165 m.found = 0;
2166 for (n = (objectfile *) y->hhead; n != NULL; n = n->next)
2167 {
2168 m.symbols = n->symbols;
2169 m.base = n->base;
2170 bfd_map_over_sections(n->file, findsource, &m);
2171 if (m.found)
2172 {
2173 *s = m.func;
2174 *t = m.file;
2175 *u = m.line;
2176 return 1;
2177 }
2178 }
2179 #endif /* FORMAT */
2180 *s = *t = NULL;
2181 *u = 0;
2182 #if DYNLINK == DYNLINK_WINDOWS
2183 if (y->lineinfo)
2184 {
2185 i = (IMAGEHLP_SYMBOL *) b;
2186 i->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
2187 i->MaxNameLength = sizeof(b) - sizeof(IMAGEHLP_SYMBOL);
2188 if (SymGetSymFromAddr(GetCurrentProcess(), (unsigned long) p, &d, i))
2189 *s = i->Name;
2190 l.SizeOfStruct = sizeof(IMAGEHLP_LINE);
2191 if (SymGetLineFromAddr(GetCurrentProcess(), (unsigned long) p, &d, &l))
2192 {
2193 *t = l.FileName;
2194 *u = l.LineNumber;
2195 }
2196 if ((*s != NULL) || (*t != NULL))
2197 return 1;
2198 }
2199 #endif /* DYNLINK */
2200 return 0;
2201 }
2202
2203
2204 #ifdef __cplusplus
2205 }
2206 #endif /* __cplusplus */
2207