This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / strip / strip.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1988 Regents of the University of California.\n\
37 All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
8bcfe259
RG
41/*static char sccsid[] = "from: @(#)strip.c 5.8 (Berkeley) 11/6/91";*/
42static char rcsid[] = "$Id: strip.c,v 1.6 1993/09/07 16:12:15 brezak Exp $";
15637ed4
RG
43#endif /* not lint */
44
45#include <sys/types.h>
46#include <sys/stat.h>
d803fffd 47#include <sys/mman.h>
15637ed4
RG
48#include <fcntl.h>
49#include <errno.h>
50#include <a.out.h>
51#include <unistd.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55
56typedef struct exec EXEC;
57typedef struct nlist NLIST;
58
d803fffd
AM
59#define strx n_un.n_strx
60
15637ed4
RG
61void err __P((const char *fmt, ...));
62void s_stab __P((const char *, int, EXEC *));
63void s_sym __P((const char *, int, EXEC *));
64void usage __P((void));
65
8bcfe259
RG
66int xflag = 0;
67
15637ed4
RG
68main(argc, argv)
69 int argc;
70 char *argv[];
71{
72 register int fd, nb;
73 EXEC head;
74 void (*sfcn)__P((const char *, int, EXEC *));
75 int ch;
76 char *fn;
77
78 sfcn = s_sym;
8bcfe259 79 while ((ch = getopt(argc, argv, "dx")) != EOF)
15637ed4 80 switch(ch) {
8bcfe259
RG
81 case 'x':
82 xflag = 1;
83 /*FALLTHROUGH*/
15637ed4
RG
84 case 'd':
85 sfcn = s_stab;
86 break;
87 case '?':
88 default:
89 usage();
90 }
91 argc -= optind;
92 argv += optind;
93
94 while (fn = *argv++) {
95 if ((fd = open(fn, O_RDWR)) < 0 ||
96 (nb = read(fd, &head, sizeof(EXEC))) == -1) {
97 err("%s: %s", fn, strerror(errno));
98 continue;
99 }
100 if (nb != sizeof(EXEC) || N_BADMAG(head)) {
101 err("%s: %s", fn, strerror(EFTYPE));
102 continue;
103 }
104 sfcn(fn, fd, &head);
105 if (close(fd))
106 err("%s: %s", fn, strerror(errno));
107 }
d803fffd 108 exit(0);
15637ed4
RG
109}
110
111void
112s_sym(fn, fd, ep)
113 const char *fn;
114 int fd;
115 register EXEC *ep;
116{
15637ed4
RG
117 register off_t fsize;
118
119 /* If no symbols or data/text relocation info, quit. */
120 if (!ep->a_syms && !ep->a_trsize && !ep->a_drsize)
121 return;
122
123 /*
124 * New file size is the header plus text and data segments; OMAGIC
125 * and NMAGIC formats have the text/data immediately following the
126 * header. ZMAGIC format wastes the rest of of header page.
127 */
8bcfe259 128 fsize = N_RELOFF(*ep);
15637ed4
RG
129
130 /* Set symbol size and relocation info values to 0. */
131 ep->a_syms = ep->a_trsize = ep->a_drsize = 0;
132
133 /* Rewrite the header and truncate the file. */
134 if (lseek(fd, 0L, SEEK_SET) == -1 ||
135 write(fd, ep, sizeof(EXEC)) != sizeof(EXEC) ||
136 ftruncate(fd, fsize))
137 err("%s: %s", fn, strerror(errno));
138}
139
140void
141s_stab(fn, fd, ep)
142 const char *fn;
143 int fd;
144 EXEC *ep;
145{
d803fffd
AM
146 register int cnt, len, nsymcnt;
147 register char *nstr, *nstrbase, *p, *strbase;
148 register NLIST *sym, *nsym;
15637ed4 149 struct stat sb;
d803fffd 150 NLIST *symbase;
15637ed4
RG
151
152 /* Quit if no symbols. */
153 if (ep->a_syms == 0)
154 return;
155
d803fffd
AM
156 /* Map the file. */
157 if (fstat(fd, &sb) ||
158 (ep = (EXEC *)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
159 MAP_FILE | MAP_SHARED, fd, (off_t)0)) == (EXEC *)-1)
160 err("%s: %s", fn, strerror(errno));
15637ed4 161
d803fffd
AM
162 /*
163 * Initialize old and new symbol pointers. They both point to the
164 * beginning of the symbol table in memory, since we're deleting
165 * entries.
166 */
167 sym = nsym = symbase = (NLIST *)((char *)ep + N_SYMOFF(*ep));
15637ed4
RG
168
169 /*
d803fffd
AM
170 * Allocate space for the new string table, initialize old and
171 * new string pointers. Handle the extra long at the beginning
172 * of the string table.
15637ed4 173 */
d803fffd
AM
174 strbase = (char *)ep + N_STROFF(*ep);
175 if ((nstrbase = malloc((u_int)*(u_long *)strbase)) == NULL)
15637ed4 176 err("%s", strerror(errno));
d803fffd 177 nstr = nstrbase + sizeof(u_long);
15637ed4
RG
178
179 /*
180 * Read through the symbol table. For each non-debugging symbol,
d803fffd
AM
181 * copy it and save its string in the new string table. Keep
182 * track of the number of symbols.
15637ed4 183 */
d803fffd
AM
184 for (cnt = ep->a_syms / sizeof(NLIST); cnt--; ++sym)
185 if (!(sym->n_type & N_STAB) && sym->strx) {
186 *nsym = *sym;
187 nsym->strx = nstr - nstrbase;
188 p = strbase + sym->strx;
8bcfe259
RG
189 if (xflag &&
190 (!(sym->n_type & N_EXT) ||
191 (sym->n_type & ~N_EXT) == N_FN ||
192 strcmp(p, "gcc_compiled.") == 0 ||
193 strcmp(p, "gcc2_compiled.") == 0 ||
194 strcmp(p, "___gnu_compiled_c") == 0)) {
195 continue;
196 }
15637ed4 197 len = strlen(p) + 1;
d803fffd
AM
198 bcopy(p, nstr, len);
199 nstr += len;
200 ++nsym;
15637ed4
RG
201 }
202
15637ed4 203 /* Fill in new symbol table size. */
d803fffd 204 ep->a_syms = (nsym - symbase) * sizeof(NLIST);
15637ed4
RG
205
206 /* Fill in the new size of the string table. */
d803fffd 207 *(u_long *)nstrbase = len = nstr - nstrbase;
15637ed4 208
d803fffd
AM
209 /*
210 * Copy the new string table into place. Nsym should be pointing
211 * at the address past the last symbol entry.
212 */
213 bcopy(nstrbase, (void *)nsym, len);
15637ed4
RG
214
215 /* Truncate to the current length. */
d803fffd
AM
216 if (ftruncate(fd, (char *)nsym + len - (char *)ep))
217 err("%s: %s", fn, strerror(errno));
218 munmap((caddr_t)ep, sb.st_size);
15637ed4
RG
219}
220
221void
222usage()
223{
15637ed4
RG
224 (void)fprintf(stderr, "usage: strip [-d] file ...\n");
225 exit(1);
226}
227
228#if __STDC__
229#include <stdarg.h>
230#else
231#include <varargs.h>
232#endif
233
234void
235#if __STDC__
236err(const char *fmt, ...)
237#else
238err(fmt, va_alist)
239 char *fmt;
240 va_dcl
241#endif
242{
243 va_list ap;
244#if __STDC__
245 va_start(ap, fmt);
246#else
247 va_start(ap);
248#endif
249 (void)fprintf(stderr, "strip: ");
250 (void)vfprintf(stderr, fmt, ap);
251 va_end(ap);
252 (void)fprintf(stderr, "\n");
d803fffd 253 exit(1);
15637ed4 254}