* Copyright (c) 1988 Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1988 Regents of the University of California.\n\
static char sccsid
[] = "@(#)strip.c 5.12 (Berkeley) %G%";
typedef struct exec EXEC
;
typedef struct nlist NLIST
;
void err
__P((int, const char *fmt
, ...));
void s_stab
__P((const char *, int, EXEC
*));
void s_sym
__P((const char *, int, EXEC
*));
void (*sfcn
)__P((const char *, int, EXEC
*));
while ((ch
= getopt(argc
, argv
, "d")) != EOF
)
if ((fd
= open(fn
, O_RDWR
)) < 0 ||
(nb
= read(fd
, &head
, sizeof(EXEC
))) == -1) {
err(0, "%s: %s", fn
, strerror(errno
));
if (nb
!= sizeof(EXEC
) || N_BADMAG(head
)) {
err(0, "%s: %s", fn
, strerror(EFTYPE
));
err(0, "%s: %s", fn
, strerror(errno
));
static int pagesize
= -1;
/* If no symbols or data/text relocation info, quit. */
if (!ep
->a_syms
&& !ep
->a_trsize
&& !ep
->a_drsize
)
* New file size is the header plus text and data segments; OMAGIC
* and NMAGIC formats have the text/data immediately following the
* header. ZMAGIC format wastes the rest of of header page.
if (ep
->a_magic
== ZMAGIC
)
fsize
= pagesize
== -1 ? (pagesize
= getpagesize()) : pagesize
;
fsize
+= ep
->a_text
+ ep
->a_data
;
/* Set symbol size and relocation info values to 0. */
ep
->a_syms
= ep
->a_trsize
= ep
->a_drsize
= 0;
/* Rewrite the header and truncate the file. */
if (lseek(fd
, (off_t
)0, SEEK_SET
) == -1 ||
write(fd
, ep
, sizeof(EXEC
)) != sizeof(EXEC
) ||
err(0, "%s: %s", fn
, strerror(errno
));
register char *nstr
, *nstrbase
, *p
, *strbase
;
register NLIST
*sym
, *nsym
;
/* Quit if no symbols. */
if (fstat(fd
, &sb
) < 0) {
err(0, "%s: %s", fn
, strerror(errno
));
if (sb
.st_size
> SIZE_T_MAX
) {
err(0, "%s: %s", fn
, strerror(EFBIG
));
if ((ep
= (EXEC
*)mmap(NULL
, (size_t)sb
.st_size
,
PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, (off_t
)0)) == (EXEC
*)-1) {
err(0, "%s: %s", fn
, strerror(errno
));
* Initialize old and new symbol pointers. They both point to the
* beginning of the symbol table in memory, since we're deleting
sym
= nsym
= symbase
= (NLIST
*)((char *)ep
+ N_SYMOFF(*ep
));
* Allocate space for the new string table, initialize old and
* new string pointers. Handle the extra long at the beginning
strbase
= (char *)ep
+ N_STROFF(*ep
);
if ((nstrbase
= malloc((u_int
)*(u_long
*)strbase
)) == NULL
)
err(1, "%s", strerror(errno
));
nstr
= nstrbase
+ sizeof(u_long
);
* Read through the symbol table. For each non-debugging symbol,
* copy it and save its string in the new string table. Keep
* track of the number of symbols.
for (cnt
= ep
->a_syms
/ sizeof(NLIST
); cnt
--; ++sym
)
if (!(sym
->n_type
& N_STAB
) && sym
->strx
) {
nsym
->strx
= nstr
- nstrbase
;
/* Fill in new symbol table size. */
ep
->a_syms
= (nsym
- symbase
) * sizeof(NLIST
);
/* Fill in the new size of the string table. */
*(u_long
*)nstrbase
= len
= nstr
- nstrbase
;
* Copy the new string table into place. Nsym should be pointing
* at the address past the last symbol entry.
bcopy(nstrbase
, (void *)nsym
, len
);
/* Truncate to the current length. */
if (ftruncate(fd
, (char *)nsym
+ len
- (char *)ep
))
err(0, "%s: %s", fn
, strerror(errno
));
munmap((caddr_t
)ep
, (size_t)sb
.st_size
);
(void)fprintf(stderr
, "usage: strip [-d] file ...\n");
err(int fatal
, const char *fmt
, ...)
err(fatal
, fmt
, va_alist
)
(void)fprintf(stderr
, "strip: ");
(void)vfprintf(stderr
, fmt
, ap
);
(void)fprintf(stderr
, "\n");