13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*4de34a7eSDavid du Colombier #include <bio.h>
4*4de34a7eSDavid du Colombier #include <mach.h>
53e12c5d1SDavid du Colombier
6*4de34a7eSDavid du Colombier void
error(char * fmt,...)7*4de34a7eSDavid du Colombier error(char* fmt, ...)
8*4de34a7eSDavid du Colombier {
9*4de34a7eSDavid du Colombier va_list arg;
10*4de34a7eSDavid du Colombier char *e, s[256];
11*4de34a7eSDavid du Colombier
12*4de34a7eSDavid du Colombier va_start(arg, fmt);
13*4de34a7eSDavid du Colombier e = seprint(s, s+sizeof(s), "%s: ", argv0);
14*4de34a7eSDavid du Colombier e = vseprint(e, s+sizeof(s), fmt, arg);
15*4de34a7eSDavid du Colombier e = seprint(e, s+sizeof(s), "\n");
16*4de34a7eSDavid du Colombier va_end(arg);
17*4de34a7eSDavid du Colombier
18*4de34a7eSDavid du Colombier write(2, s, e-s);
19*4de34a7eSDavid du Colombier }
20*4de34a7eSDavid du Colombier
21*4de34a7eSDavid du Colombier static void
usage(void)22*4de34a7eSDavid du Colombier usage(void)
23*4de34a7eSDavid du Colombier {
24*4de34a7eSDavid du Colombier error("usage: %s -o ofile file\n\t%s file ...\n", argv0, argv0);
25*4de34a7eSDavid du Colombier exits("usage");
26*4de34a7eSDavid du Colombier }
27*4de34a7eSDavid du Colombier
28*4de34a7eSDavid du Colombier static int
strip(char * file,char * out)29*4de34a7eSDavid du Colombier strip(char* file, char* out)
30*4de34a7eSDavid du Colombier {
31*4de34a7eSDavid du Colombier Dir *dir;
32*4de34a7eSDavid du Colombier int fd, i;
33*4de34a7eSDavid du Colombier Fhdr fhdr;
34*4de34a7eSDavid du Colombier Exec *exec;
35*4de34a7eSDavid du Colombier ulong mode;
36*4de34a7eSDavid du Colombier void *data;
37*4de34a7eSDavid du Colombier vlong length;
38*4de34a7eSDavid du Colombier
39*4de34a7eSDavid du Colombier if((fd = open(file, OREAD)) < 0){
40*4de34a7eSDavid du Colombier error("%s: open: %r", file);
41*4de34a7eSDavid du Colombier return 1;
42*4de34a7eSDavid du Colombier }
43*4de34a7eSDavid du Colombier
44*4de34a7eSDavid du Colombier if(!crackhdr(fd, &fhdr)){
45*4de34a7eSDavid du Colombier error("%s: %r", file);
46*4de34a7eSDavid du Colombier close(fd);
47*4de34a7eSDavid du Colombier return 1;
48*4de34a7eSDavid du Colombier }
49*4de34a7eSDavid du Colombier for(i = MIN_MAGIC; i <= MAX_MAGIC; i++){
50*4de34a7eSDavid du Colombier if(fhdr.magic == _MAGIC(0, i) || fhdr.magic == _MAGIC(HDR_MAGIC, i))
51*4de34a7eSDavid du Colombier break;
52*4de34a7eSDavid du Colombier }
53*4de34a7eSDavid du Colombier if(i > MAX_MAGIC){
54*4de34a7eSDavid du Colombier error("%s: not a recognizeable binary", file);
55*4de34a7eSDavid du Colombier close(fd);
56*4de34a7eSDavid du Colombier return 1;
57*4de34a7eSDavid du Colombier }
58*4de34a7eSDavid du Colombier
59*4de34a7eSDavid du Colombier if((dir = dirfstat(fd)) == nil){
60*4de34a7eSDavid du Colombier error("%s: stat: %r", file);
61*4de34a7eSDavid du Colombier close(fd);
62*4de34a7eSDavid du Colombier return 1;
63*4de34a7eSDavid du Colombier }
64*4de34a7eSDavid du Colombier
65*4de34a7eSDavid du Colombier length = fhdr.datoff+fhdr.datsz;
66*4de34a7eSDavid du Colombier if(length == dir->length){
67*4de34a7eSDavid du Colombier if(out == nil){ /* nothing to do */
68*4de34a7eSDavid du Colombier error("%s: already stripped", file);
69*4de34a7eSDavid du Colombier free(dir);
70*4de34a7eSDavid du Colombier close(fd);
71*4de34a7eSDavid du Colombier return 0;
72*4de34a7eSDavid du Colombier }
73*4de34a7eSDavid du Colombier }
74*4de34a7eSDavid du Colombier if(length > dir->length){
75*4de34a7eSDavid du Colombier error("%s: strange length", file);
76*4de34a7eSDavid du Colombier close(fd);
77*4de34a7eSDavid du Colombier free(dir);
78*4de34a7eSDavid du Colombier return 1;
79*4de34a7eSDavid du Colombier }
80*4de34a7eSDavid du Colombier
81*4de34a7eSDavid du Colombier mode = dir->mode;
82*4de34a7eSDavid du Colombier free(dir);
83*4de34a7eSDavid du Colombier
84*4de34a7eSDavid du Colombier if((data = malloc(length)) == nil){
85*4de34a7eSDavid du Colombier error("%s: malloc failure", file);
86*4de34a7eSDavid du Colombier close(fd);
87*4de34a7eSDavid du Colombier return 1;
88*4de34a7eSDavid du Colombier }
89*4de34a7eSDavid du Colombier seek(fd, 0LL, 0);
90*4de34a7eSDavid du Colombier if(read(fd, data, length) != length){
91*4de34a7eSDavid du Colombier error("%s: read: %r", file);
92*4de34a7eSDavid du Colombier close(fd);
93*4de34a7eSDavid du Colombier free(data);
94*4de34a7eSDavid du Colombier return 1;
95*4de34a7eSDavid du Colombier }
96*4de34a7eSDavid du Colombier close(fd);
97*4de34a7eSDavid du Colombier
98*4de34a7eSDavid du Colombier exec = data;
99*4de34a7eSDavid du Colombier exec->syms = 0;
100*4de34a7eSDavid du Colombier exec->spsz = 0;
101*4de34a7eSDavid du Colombier exec->pcsz = 0;
102*4de34a7eSDavid du Colombier
103*4de34a7eSDavid du Colombier if(out == nil){
104*4de34a7eSDavid du Colombier if(remove(file) < 0) {
105*4de34a7eSDavid du Colombier error("%s: remove: %r", file);
106*4de34a7eSDavid du Colombier free(data);
107*4de34a7eSDavid du Colombier return 1;
108*4de34a7eSDavid du Colombier }
109*4de34a7eSDavid du Colombier out = file;
110*4de34a7eSDavid du Colombier }
111*4de34a7eSDavid du Colombier if((fd = create(out, OWRITE, mode)) < 0){
112*4de34a7eSDavid du Colombier error("%s: create: %r", out);
113*4de34a7eSDavid du Colombier free(data);
114*4de34a7eSDavid du Colombier return 1;
115*4de34a7eSDavid du Colombier }
116*4de34a7eSDavid du Colombier if(write(fd, data, length) != length){
117*4de34a7eSDavid du Colombier error("%s: write: %r", out);
118*4de34a7eSDavid du Colombier close(fd);
119*4de34a7eSDavid du Colombier free(data);
120*4de34a7eSDavid du Colombier return 1;
121*4de34a7eSDavid du Colombier }
122*4de34a7eSDavid du Colombier close(fd);
123*4de34a7eSDavid du Colombier free(data);
124*4de34a7eSDavid du Colombier
125*4de34a7eSDavid du Colombier return 0;
126*4de34a7eSDavid du Colombier }
127*4de34a7eSDavid du Colombier
1283e12c5d1SDavid du Colombier void
main(int argc,char * argv[])1293e12c5d1SDavid du Colombier main(int argc, char* argv[])
1303e12c5d1SDavid du Colombier {
131*4de34a7eSDavid du Colombier int r;
132*4de34a7eSDavid du Colombier char *p;
1333e12c5d1SDavid du Colombier
134*4de34a7eSDavid du Colombier p = nil;
1357dd7cddfSDavid du Colombier
136*4de34a7eSDavid du Colombier ARGBEGIN{
137*4de34a7eSDavid du Colombier default:
138*4de34a7eSDavid du Colombier usage();
139*4de34a7eSDavid du Colombier break;
140*4de34a7eSDavid du Colombier case 'o':
141*4de34a7eSDavid du Colombier p = ARGF();
142*4de34a7eSDavid du Colombier if(p == nil)
143*4de34a7eSDavid du Colombier usage();
144*4de34a7eSDavid du Colombier break;
145*4de34a7eSDavid du Colombier }ARGEND;
146*4de34a7eSDavid du Colombier
147*4de34a7eSDavid du Colombier switch(argc){
148*4de34a7eSDavid du Colombier case 0:
149*4de34a7eSDavid du Colombier usage();
150*4de34a7eSDavid du Colombier return;
151*4de34a7eSDavid du Colombier case 1:
152*4de34a7eSDavid du Colombier if(p != nil){
153*4de34a7eSDavid du Colombier r = strip(*argv, p);
154*4de34a7eSDavid du Colombier break;
155*4de34a7eSDavid du Colombier }
156*4de34a7eSDavid du Colombier /*FALLTHROUGH*/
157*4de34a7eSDavid du Colombier default:
158*4de34a7eSDavid du Colombier r = 0;
159*4de34a7eSDavid du Colombier while(argc > 0){
160*4de34a7eSDavid du Colombier r |= strip(*argv, nil);
161*4de34a7eSDavid du Colombier argc--;
162*4de34a7eSDavid du Colombier argv++;
163*4de34a7eSDavid du Colombier }
164*4de34a7eSDavid du Colombier break;
165*4de34a7eSDavid du Colombier }
166*4de34a7eSDavid du Colombier
167*4de34a7eSDavid du Colombier if(r)
1687dd7cddfSDavid du Colombier exits("error");
1697dd7cddfSDavid du Colombier exits(0);
1707dd7cddfSDavid du Colombier }
171