64-bit fixes.
[rsc] --rw-rw-r-- M 451989 glenda sys 523 Nov 6 11:07 sys/man/1/strip
/n/sourcesdump/2005/1106/plan9/sys/man/1/strip:3,18 -
/n/sourcesdump/2005/1107/plan9/sys/man/1/strip:3,30
strip \- remove symbols from binary files
.SH SYNOPSIS
.B strip
- [
.I file ...
- ]
+ .PP
+ .B strip
+ .B -o
+ .I ofile
+ .I file
.SH DESCRIPTION
.I Strip
- removes symbol table segments from executable files, rewriting the files in place.
+ removes symbol table segments from executable files,
+ rewriting the files in place.
Stripping a file requires write permission of the file
and the directory it is in.
- If no file is given,
- standard input is stripped and the result written to standard output.
+ .PP
+ If the
+ .B -o
+ flag is given,
+ the single input file
+ .I file
+ is stripped and the result written to
+ .IR ofile .
+ .I File
+ is unchanged.
.SH SOURCE
.B /sys/src/cmd/strip.c
.SH "SEE ALSO"
[rsc] --rw-rw-r-- M 451989 glenda sys 2502 Nov 6 11:07 sys/src/cmd/strip.c
/n/sourcesdump/2005/1106/plan9/sys/src/cmd/strip.c:1,206 -
/n/sourcesdump/2005/1107/plan9/sys/src/cmd/strip.c:1,170
#include <u.h>
#include <libc.h>
- #include <a.out.h>
+ #include <bio.h>
+ #include <mach.h>
- int strip(char*);
- int stripfilt(int, int);
void
- main(int argc, char *argv[])
+ error(char* fmt, ...)
{
- int i;
- int rv;
+ va_list arg;
+ char *e, s[256];
- rv = 0;
+ va_start(arg, fmt);
+ e = seprint(s, s+sizeof(s), "%s: ", argv0);
+ e = vseprint(e, s+sizeof(s), fmt, arg);
+ e = seprint(e, s+sizeof(s), "\n");
+ va_end(arg);
- if(argc == 1) {
- if(stripfilt(0, 1))
- exits("error");
- exits(0);
- }
-
- for(i = 1; i < argc; i++)
- rv |= strip(argv[i]);
- if(rv)
- exits("error");
- exits(0);
+ write(2, s, e-s);
}
- long
- ben(long xen)
+ static void
+ usage(void)
{
- union
- {
- long xen;
- uchar uch[sizeof(long)];
- } u;
-
- u.xen = xen;
- return (u.uch[0] << 24) | (u.uch[1] << 16) | (u.uch[2] << 8) | (u.uch[3] << 0);
+ error("usage: %s -o ofile file\n\t%s file ...\n", argv0, argv0);
+ exits("usage");
}
- int
- stripfilt(int in, int out)
+ static int
+ strip(char* file, char* out)
{
- Exec exec;
- int i, j, n, m, len;
- char buf[8192];
+ Dir *dir;
+ int fd, i;
+ Fhdr fhdr;
+ Exec *exec;
+ ulong mode;
+ void *data;
+ vlong length;
- /*
- * read header
- */
-
- if(readn(in, &exec, sizeof(Exec)) != sizeof(Exec)) {
- fprint(2, "strip: short read\n");
+ if((fd = open(file, OREAD)) < 0){
+ error("%s: open: %r", file);
return 1;
}
- i = ben(exec.magic);
- for (j = MIN_MAGIC; j <= MAX_MAGIC; j++)
- if (i == _MAGIC(j))
- break;
- if (j > MAX_MAGIC) {
- fprint(2, "strip: not a recognizable binary\n");
- return 1;
- }
- len = ben(exec.data) + ben(exec.text);
-
- /*
- * copy exec, text and data
- */
- exec.syms = 0;
- exec.spsz = 0;
- exec.pcsz = 0;
- write(out, &exec, sizeof(exec));
-
- for(n=0; n<len; n+=m) {
- m = len - n;
- if(m > sizeof(buf))
- m = sizeof(buf);
- if((m = read(in, buf, m)) < 0) {
- fprint(2, "strip: premature eof: %r\n");
- return 1;
- }
- if(write(out, buf, m) != m) {
- fprint(2, "strip: write error; %r\n");
- return 1;
- }
- }
-
- return 0;
- }
-
-
- int
- strip(char *file)
- {
- int fd;
- Exec exec;
- char *data;
- Dir *d;
- long n, len;
- int i, j;
-
- /*
- * make sure file is executable
- */
- d = dirstat(file);
- if(d == nil){
- perror(file);
+ if(!crackhdr(fd, &fhdr)){
+ error("%s: %r", file);
+ close(fd);
return 1;
}
- if((d->qid.path & (DMDIR|DMAPPEND|DMEXCL))){
- fprint(2, "strip: %s must be executable\n", file);
- return 1;
+ for(i = MIN_MAGIC; i <= MAX_MAGIC; i++){
+ if(fhdr.magic == _MAGIC(0, i) || fhdr.magic == _MAGIC(HDR_MAGIC, i))
+ break;
}
- /*
- * read its header and see if that makes sense
- */
- fd = open(file, OREAD);
- if(fd < 0){
- perror(file);
- free(d);
- return 1;
- }
- n = read(fd, &exec, sizeof exec);
- if (n != sizeof(exec)) {
- fprint(2, "strip: Unable to read header of %s\n", file);
+ if(i > MAX_MAGIC){
+ error("%s: not a recognizeable binary", file);
close(fd);
- free(d);
return 1;
}
- i = ben(exec.magic);
- for (j = MIN_MAGIC; j <= MAX_MAGIC; j++)
- if (i == _MAGIC(j))
- break;
- if (j > MAX_MAGIC) {
- fprint(2, "strip: %s is not a recognizable binary\n", file);
+
+ if((dir = dirfstat(fd)) == nil){
+ error("%s: stat: %r", file);
close(fd);
- free(d);
return 1;
}
- len = ben(exec.data) + ben(exec.text);
- if(len+sizeof(exec) == d->length) {
- fprint(2, "strip: %s is already stripped\n", file);
- close(fd);
- free(d);
- return 0;
+ length = fhdr.datoff+fhdr.datsz;
+ if(length == dir->length){
+ if(out == nil){ /* nothing to do */
+ error("%s: already stripped", file);
+ free(dir);
+ close(fd);
+ return 0;
+ }
}
- if(len+sizeof(exec) > d->length) {
- fprint(2, "strip: %s has strange length\n", file);
+ if(length > dir->length){
+ error("%s: strange length", file);
close(fd);
- free(d);
+ free(dir);
return 1;
}
- /*
- * allocate a huge buffer, copy the header into it, then
- * read the file.
- */
- data = malloc(len+sizeof(exec));
- if (!data) {
- fprint(2, "strip: Malloc failure. %s too big to strip.\n", file);
+
+ mode = dir->mode;
+ free(dir);
+
+ if((data = malloc(length)) == nil){
+ error("%s: malloc failure", file);
close(fd);
- free(d);
return 1;
}
- /*
- * copy exec, text and data
- */
- exec.syms = 0;
- exec.spsz = 0;
- exec.pcsz = 0;
- memcpy(data, &exec, sizeof(exec));
- n = read(fd, data+sizeof(exec), len);
- if (n != len) {
- perror(file);
+ seek(fd, 0LL, 0);
+ if(read(fd, data, length) != length){
+ error("%s: read: %r", file);
close(fd);
- free(d);
+ free(data);
return 1;
}
close(fd);
- if(remove(file) < 0) {
- perror(file);
- free(data);
- free(d);
- return 1;
+
+ exec = data;
+ exec->syms = 0;
+ exec->spsz = 0;
+ exec->pcsz = 0;
+
+ if(out == nil){
+ if(remove(file) < 0) {
+ error("%s: remove: %r", file);
+ free(data);
+ return 1;
+ }
+ out = file;
}
- fd = create(file, OWRITE, d->mode);
- if (fd < 0) {
- perror(file);
+ if((fd = create(out, OWRITE, mode)) < 0){
+ error("%s: create: %r", out);
free(data);
- free(d);
return 1;
}
- n = write(fd, data, len+sizeof(exec));
- if (n != len+sizeof(exec)) {
- perror(file);
+ if(write(fd, data, length) != length){
+ error("%s: write: %r", out);
close(fd);
free(data);
- free(d);
return 1;
- }
+ }
close(fd);
free(data);
- free(d);
+
return 0;
+ }
+
+ void
+ main(int argc, char* argv[])
+ {
+ int r;
+ char *p;
+
+ p = nil;
+
+ ARGBEGIN{
+ default:
+ usage();
+ break;
+ case 'o':
+ p = ARGF();
+ if(p == nil)
+ usage();
+ break;
+ }ARGEND;
+
+ switch(argc){
+ case 0:
+ usage();
+ return;
+ case 1:
+ if(p != nil){
+ r = strip(*argv, p);
+ break;
+ }
+ /*FALLTHROUGH*/
+ default:
+ r = 0;
+ while(argc > 0){
+ r |= strip(*argv, nil);
+ argc--;
+ argv++;
+ }
+ break;
+ }
+
+ if(r)
+ exits("error");
+ exits(0);
}
|