386BSD 0.1 development
[unix-history] / usr / src / usr.sbin / dbsym / dbsym.c
CommitLineData
ad7b3f66
WJ
1/* Written by Pace Willisson (pace@blitz.com)
2 * and placed in the public domain.
3 */
4#include <stdio.h>
5#include <a.out.h>
6
7char *malloc ();
8
9#define FILE_OFFSET(vadr) (((vadr) & ~0xff000000)-N_DATADDR(hdr)+N_DATOFF(hdr))
10
11struct nlist *old_syms;
12int num_old_syms;
13char *old_strtab;
14int old_strtab_size;
15
16struct nlist *new_syms;
17int num_new_syms;
18int new_syms_bytes;
19char *new_strtab;
20int new_strtab_size;
21
22int db_symtabsize_adr;
23int db_symtab_adr;
24
25int avail;
26
27
28usage ()
29{
30 fprintf (stderr, "usage: dbsym file\n");
31 exit (1);
32}
33
34struct exec hdr;
35
36main (argc, argv)
37char **argv;
38{
39 FILE *f;
40 char *name;
41 extern int optind;
42 int c, i;
43 int need;
44 char *buf, *p;
45 struct nlist *nsp, *sp;
46 int len;
47
48
49 while ((c = getopt (argc, argv, "")) != EOF) {
50 switch (c) {
51 default:
52 usage ();
53 }
54 }
55
56 if (optind >= argc)
57 usage ();
58
59 name = argv[optind++];
60
61 if (optind != argc)
62 usage ();
63
64 if ((f = fopen (name, "r+")) == NULL) {
65 fprintf (stderr, "can't open %s\n", name);
66 exit (1);
67 }
68
69 if (fread ((char *)&hdr, sizeof hdr, 1, f) != 1) {
70 fprintf (stderr, "can't read header\n");
71 exit (1);
72 }
73
74 if (N_BADMAG (hdr)) {
75 fprintf (stderr, "bad magic number\n");
76 exit (1);
77 }
78
79 if (hdr.a_syms == 0) {
80 fprintf (stderr, "no symbols\n");
81 exit (1);
82 }
83
84 fseek (f, N_STROFF (hdr), 0);
85 if (fread ((char *)&old_strtab_size, sizeof (int), 1, f) != 1) {
86 fprintf (stderr, "can't read old strtab size\n");
87 exit (1);
88 }
89
90 if ((old_syms = (struct nlist *)malloc (hdr.a_syms)) == NULL
91 || ((old_strtab = malloc (old_strtab_size)) == NULL)
92 || ((new_syms = (struct nlist *)malloc (hdr.a_syms)) == NULL)
93 || ((new_strtab = malloc (old_strtab_size)) == NULL)) {
94 fprintf (stderr, "out of memory\n");
95 exit (1);
96 }
97
98 fseek (f, N_SYMOFF (hdr), 0);
99 if (fread ((char *)old_syms, hdr.a_syms, 1, f) != 1) {
100 fprintf (stderr, "can't read symbols\n");
101 exit (1);
102 }
103
104 fseek (f, N_STROFF (hdr), 0);
105 if (fread ((char *)old_strtab, old_strtab_size, 1, f) != 1) {
106 fprintf (stderr, "can't read string table\n");
107 exit (1);
108 }
109
110 num_old_syms = hdr.a_syms / sizeof (struct nlist);
111
112 new_strtab_size = 4;
113
114 nsp = new_syms;
115 for (i = 0, sp = old_syms; i < num_old_syms; i++, sp++) {
116 if (sp->n_type & N_STAB)
117 continue;
118 if (sp->n_un.n_strx == 0)
119 continue;
120
121 if (sp->n_value < 0xfe000000)
122 continue;
123
124 if (sp->n_value >= 0xff000000)
125 continue;
126
127 name = old_strtab + sp->n_un.n_strx;
128
129 len = strlen (name);
130
131 if (len == 0)
132 continue;
133
134 if (len >= 2 && name[len - 2] == '.' && name[len - 1] == 'o')
135 continue;
136
137 if (strcmp (name, "gcc_compiled.") == 0)
138 continue;
139
140 *nsp = *sp;
141
142 nsp->n_un.n_strx = new_strtab_size;
143 strcpy (new_strtab + new_strtab_size, name);
144 new_strtab_size += len + 1;
145 nsp++;
146
147 if (strcmp (name, "_db_symtab") == 0)
148 db_symtab_adr = sp->n_value;
149 if (strcmp (name, "_db_symtabsize") == 0)
150 db_symtabsize_adr = sp->n_value;
151 }
152
153 if (db_symtab_adr == 0 || db_symtabsize_adr == 0) {
154 fprintf (stderr, "couldn't find db_symtab symbols\n");
155 exit (1);
156 }
157
158 *(int *)new_strtab = new_strtab_size;
159 num_new_syms = nsp - new_syms;
160 new_syms_bytes = num_new_syms * sizeof (struct nlist);
161
162 need = sizeof (int)
163 + num_new_syms * sizeof (struct nlist)
164 + new_strtab_size;
165
166 fseek (f, FILE_OFFSET (db_symtabsize_adr), 0);
167
168 if (fread ((char *)&avail, sizeof (int), 1, f) != 1) {
169 fprintf (stderr, "can't read symtabsize\n");
170 exit (1);
171 }
172
173 printf ("dbsym: need %d; avail %d\n", need, avail);
174
175 if (need > avail) {
176 fprintf (stderr, "not enough room in db_symtab array\n");
177 exit (1);
178 }
179
180 fseek (f, FILE_OFFSET (db_symtab_adr), 0);
181 fwrite ((char *)&new_syms_bytes, sizeof (int), 1, f);
182 fwrite ((char *)new_syms, new_syms_bytes, 1, f);
183 fwrite (new_strtab, new_strtab_size, 1, f);
184 fflush (f);
185
186 if (feof (f) || ferror (f)) {
187 fprintf (stderr, "write error\n");
188 exit (1);
189 }
190 exit (0);
191}
192