This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.sbin / dbsym / dbsym.c
CommitLineData
15637ed4
RG
1/* Written by Pace Willisson (pace@blitz.com)
2 * and placed in the public domain.
3 */
724622d1
RG
4
5#ifndef lint
6static char rcsid[] = "$Id: dbsym.c,v 1.8 1993/08/02 17:57:02 mycroft Exp $";
7#endif /* not lint */
8
15637ed4 9#include <stdio.h>
724622d1 10#include <stdlib.h>
15637ed4 11#include <a.out.h>
724622d1
RG
12#include <stab.h>
13#include <machine/param.h>
15637ed4 14
724622d1
RG
15#define FILE_OFFSET(vadr) (((vadr) - text_adr) - N_DATADDR(hdr) + \
16 N_DATOFF(hdr) + N_TXTADDR(hdr))
15637ed4 17
724622d1 18u_int text_adr = KERNBASE;
15637ed4
RG
19
20struct nlist *old_syms;
21int num_old_syms;
22char *old_strtab;
23int old_strtab_size;
24
25struct nlist *new_syms;
26int num_new_syms;
27int new_syms_bytes;
28char *new_strtab;
29int new_strtab_size;
30
31int db_symtabsize_adr;
32int db_symtab_adr;
33
34int avail;
35
724622d1
RG
36int force = 0;
37int zap_locals = 0;
38int debugging = 0;
15637ed4
RG
39
40usage ()
41{
724622d1 42 fprintf (stderr, "usage: dbsym [-fgx] [-T addr] file\n");
15637ed4
RG
43 exit (1);
44}
45
46struct exec hdr;
47
48main (argc, argv)
49char **argv;
50{
51 FILE *f;
52 char *name;
53 extern int optind;
54 int c, i;
55 int need;
56 char *buf, *p;
57 struct nlist *nsp, *sp;
58 int len;
59
60
724622d1 61 while ((c = getopt (argc, argv, "fgxT:")) != EOF) {
15637ed4 62 switch (c) {
724622d1
RG
63 case 'f':
64 force = 1;
65 break;
66 case 'g':
67 debugging = 1;
68 break;
69 case 'x':
70 zap_locals = 1;
71 break;
72 case 'T':
73 text_adr = strtoul(optarg, &p, 16);
74 if (*p)
75 err("illegal text address: %s", optarg);
76 break;
15637ed4
RG
77 default:
78 usage ();
79 }
80 }
81
82 if (optind >= argc)
83 usage ();
84
85 name = argv[optind++];
86
87 if (optind != argc)
88 usage ();
89
90 if ((f = fopen (name, "r+")) == NULL) {
91 fprintf (stderr, "can't open %s\n", name);
92 exit (1);
93 }
94
95 if (fread ((char *)&hdr, sizeof hdr, 1, f) != 1) {
96 fprintf (stderr, "can't read header\n");
97 exit (1);
98 }
99
100 if (N_BADMAG (hdr)) {
101 fprintf (stderr, "bad magic number\n");
102 exit (1);
103 }
104
105 if (hdr.a_syms == 0) {
106 fprintf (stderr, "no symbols\n");
107 exit (1);
108 }
109
110 fseek (f, N_STROFF (hdr), 0);
111 if (fread ((char *)&old_strtab_size, sizeof (int), 1, f) != 1) {
112 fprintf (stderr, "can't read old strtab size\n");
113 exit (1);
114 }
115
116 if ((old_syms = (struct nlist *)malloc (hdr.a_syms)) == NULL
117 || ((old_strtab = malloc (old_strtab_size)) == NULL)
118 || ((new_syms = (struct nlist *)malloc (hdr.a_syms)) == NULL)
119 || ((new_strtab = malloc (old_strtab_size)) == NULL)) {
120 fprintf (stderr, "out of memory\n");
121 exit (1);
122 }
123
124 fseek (f, N_SYMOFF (hdr), 0);
125 if (fread ((char *)old_syms, hdr.a_syms, 1, f) != 1) {
126 fprintf (stderr, "can't read symbols\n");
127 exit (1);
128 }
129
130 fseek (f, N_STROFF (hdr), 0);
131 if (fread ((char *)old_strtab, old_strtab_size, 1, f) != 1) {
132 fprintf (stderr, "can't read string table\n");
133 exit (1);
134 }
135
136 num_old_syms = hdr.a_syms / sizeof (struct nlist);
137
138 new_strtab_size = 4;
139
140 nsp = new_syms;
141 for (i = 0, sp = old_syms; i < num_old_syms; i++, sp++) {
724622d1
RG
142 if (zap_locals && !(sp->n_type & N_EXT))
143 continue;
144
15637ed4 145 if (sp->n_type & N_STAB)
724622d1
RG
146 switch (sp->n_type & ~N_EXT) {
147 case N_SLINE:
148 if (debugging)
149 *nsp++ = *sp;
150 continue;
151 case N_FUN:
152 case N_PSYM:
153 case N_SO:
154 if (!debugging)
155 continue;
156 goto skip_tests;
157 break;
158 default:
159 continue;
160 }
161
162 if ((sp->n_type & ~N_EXT) == N_UNDF)
163 continue;
164
165 if (!debugging && (sp->n_type & ~N_EXT) == N_FN)
15637ed4 166 continue;
724622d1 167
15637ed4
RG
168 if (sp->n_un.n_strx == 0)
169 continue;
170
724622d1 171 if (sp->n_value < text_adr)
15637ed4
RG
172 continue;
173
724622d1
RG
174 if (sp->n_value > (text_adr + hdr.a_text + hdr.a_data +
175 hdr.a_bss))
15637ed4
RG
176 continue;
177
724622d1
RG
178 skip_tests:
179
15637ed4
RG
180 name = old_strtab + sp->n_un.n_strx;
181
182 len = strlen (name);
183
184 if (len == 0)
185 continue;
186
724622d1 187 if (strcmp (name, "gcc_compiled.") == 0)
15637ed4
RG
188 continue;
189
724622d1 190 if (strcmp (name, "gcc2_compiled.") == 0)
15637ed4
RG
191 continue;
192
724622d1
RG
193 if (strcmp (name, "___gnu_compiled_c") == 0)
194 continue;
195
15637ed4
RG
196 *nsp = *sp;
197
198 nsp->n_un.n_strx = new_strtab_size;
199 strcpy (new_strtab + new_strtab_size, name);
200 new_strtab_size += len + 1;
201 nsp++;
202
203 if (strcmp (name, "_db_symtab") == 0)
204 db_symtab_adr = sp->n_value;
205 if (strcmp (name, "_db_symtabsize") == 0)
206 db_symtabsize_adr = sp->n_value;
207 }
208
724622d1
RG
209 if (db_symtab_adr == 0 || db_symtabsize_adr == 0)
210 if (!force) {
211 fprintf (stderr, "couldn't find db_symtab symbols\n");
212 exit (1);
213 } else
214 exit (0);
15637ed4
RG
215
216 *(int *)new_strtab = new_strtab_size;
217 num_new_syms = nsp - new_syms;
218 new_syms_bytes = num_new_syms * sizeof (struct nlist);
219
220 need = sizeof (int)
221 + num_new_syms * sizeof (struct nlist)
222 + new_strtab_size;
223
224 fseek (f, FILE_OFFSET (db_symtabsize_adr), 0);
225
226 if (fread ((char *)&avail, sizeof (int), 1, f) != 1) {
227 fprintf (stderr, "can't read symtabsize\n");
228 exit (1);
229 }
230
231 printf ("dbsym: need %d; avail %d\n", need, avail);
232
233 if (need > avail) {
234 fprintf (stderr, "not enough room in db_symtab array\n");
235 exit (1);
236 }
237
238 fseek (f, FILE_OFFSET (db_symtab_adr), 0);
239 fwrite ((char *)&new_syms_bytes, sizeof (int), 1, f);
240 fwrite ((char *)new_syms, new_syms_bytes, 1, f);
241 fwrite (new_strtab, new_strtab_size, 1, f);
242 fflush (f);
243
244 if (feof (f) || ferror (f)) {
245 fprintf (stderr, "write error\n");
246 exit (1);
247 }
248 exit (0);
249}
250