|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "leaky.h" |
|
6 |
|
7 #ifdef USE_COFF |
|
8 |
|
9 #define LANGUAGE_C |
|
10 #include <sym.h> |
|
11 #include <cmplrs/stsupport.h> |
|
12 #include <symconst.h> |
|
13 #include <filehdr.h> |
|
14 #include <ldfcn.h> |
|
15 #include <string.h> |
|
16 #include <stdlib.h> |
|
17 |
|
18 #ifdef IRIX4 |
|
19 extern "C" { |
|
20 extern char *demangle(char const* in); |
|
21 }; |
|
22 #else |
|
23 #include <dem.h> |
|
24 #endif |
|
25 |
|
26 static char *Demangle(char *rawName) |
|
27 { |
|
28 #ifdef IRIX4 |
|
29 return strdup(demangle(rawName)); |
|
30 #else |
|
31 char namebuf[4000]; |
|
32 demangle(rawName, namebuf); |
|
33 return strdup(namebuf); |
|
34 #endif |
|
35 } |
|
36 |
|
37 void leaky::readSymbols(const char *fileName) |
|
38 { |
|
39 LDFILE *ldptr; |
|
40 |
|
41 ldptr = ldopen(fileName, nullptr); |
|
42 if (!ldptr) { |
|
43 fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, |
|
44 fileName); |
|
45 exit(-1); |
|
46 } |
|
47 if (PSYMTAB(ldptr) == 0) { |
|
48 fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName, |
|
49 fileName); |
|
50 exit(-1); |
|
51 } |
|
52 |
|
53 long isymMax = SYMHEADER(ldptr).isymMax; |
|
54 long iextMax = SYMHEADER(ldptr).iextMax; |
|
55 long iMax = isymMax + iextMax; |
|
56 |
|
57 long alloced = 10000; |
|
58 Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000); |
|
59 Symbol* sp = syms; |
|
60 Symbol* last = syms + alloced; |
|
61 SYMR symr; |
|
62 |
|
63 for (long isym = 0; isym < iMax; isym++) { |
|
64 if (ldtbread(ldptr, isym, &symr) != SUCCESS) { |
|
65 fprintf(stderr, "%s: can't read symbol #%d\n", applicationName, |
|
66 isym); |
|
67 exit(-1); |
|
68 } |
|
69 if (isym < isymMax) { |
|
70 if ((symr.st == stStaticProc) |
|
71 || ((symr.st == stProc) && |
|
72 ((symr.sc == scText) || (symr.sc == scAbs))) |
|
73 || ((symr.st == stBlock) && |
|
74 (symr.sc == scText))) { |
|
75 // Text symbol. Set name field to point to the symbol name |
|
76 sp->name = Demangle(ldgetname(ldptr, &symr)); |
|
77 sp->address = symr.value; |
|
78 sp++; |
|
79 if (sp >= last) { |
|
80 long n = alloced + 10000; |
|
81 syms = (Symbol*) |
|
82 realloc(syms, (size_t) (sizeof(Symbol) * n)); |
|
83 last = syms + n; |
|
84 sp = syms + alloced; |
|
85 alloced = n; |
|
86 } |
|
87 } |
|
88 } |
|
89 } |
|
90 |
|
91 int interesting = sp - syms; |
|
92 if (!quiet) { |
|
93 printf("Total of %d symbols\n", interesting); |
|
94 } |
|
95 usefulSymbols = interesting; |
|
96 externalSymbols = syms; |
|
97 } |
|
98 |
|
99 #endif /* USE_COFF */ |