strip.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <mach.h>
  13. void
  14. error(char* fmt, ...)
  15. {
  16. va_list arg;
  17. char *e, s[256];
  18. va_start(arg, fmt);
  19. e = seprint(s, s+sizeof(s), "%s: ", argv0);
  20. e = vseprint(e, s+sizeof(s), fmt, arg);
  21. e = seprint(e, s+sizeof(s), "\n");
  22. va_end(arg);
  23. write(2, s, e-s);
  24. }
  25. static void
  26. usage(void)
  27. {
  28. error("usage: %s -o ofile file\n\t%s file ...\n", argv0, argv0);
  29. exits("usage");
  30. }
  31. static int
  32. strip(char* file, char* out)
  33. {
  34. Dir *dir;
  35. int fd, i;
  36. Fhdr fhdr;
  37. Exec *exec;
  38. uint32_t mode;
  39. void *data;
  40. int64_t length;
  41. if((fd = open(file, OREAD)) < 0){
  42. error("%s: open: %r", file);
  43. return 1;
  44. }
  45. if(!crackhdr(fd, &fhdr)){
  46. error("%s: %r", file);
  47. close(fd);
  48. return 1;
  49. }
  50. for(i = MIN_MAGIC; i <= MAX_MAGIC; i++){
  51. if(fhdr.magic == _MAGIC(0, i) || fhdr.magic == _MAGIC(HDR_MAGIC, i))
  52. break;
  53. }
  54. if(i > MAX_MAGIC){
  55. error("%s: not a recognizeable binary", file);
  56. close(fd);
  57. return 1;
  58. }
  59. if((dir = dirfstat(fd)) == nil){
  60. error("%s: stat: %r", file);
  61. close(fd);
  62. return 1;
  63. }
  64. length = fhdr.datoff+fhdr.datsz;
  65. if(length == dir->length){
  66. if(out == nil){ /* nothing to do */
  67. error("%s: already stripped", file);
  68. free(dir);
  69. close(fd);
  70. return 0;
  71. }
  72. }
  73. if(length > dir->length){
  74. error("%s: strange length", file);
  75. close(fd);
  76. free(dir);
  77. return 1;
  78. }
  79. mode = dir->mode;
  80. free(dir);
  81. if((data = malloc(length)) == nil){
  82. error("%s: malloc failure", file);
  83. close(fd);
  84. return 1;
  85. }
  86. seek(fd, 0LL, 0);
  87. if(read(fd, data, length) != length){
  88. error("%s: read: %r", file);
  89. close(fd);
  90. free(data);
  91. return 1;
  92. }
  93. close(fd);
  94. exec = data;
  95. exec->syms = 0;
  96. exec->spsz = 0;
  97. exec->pcsz = 0;
  98. if(out == nil){
  99. if(remove(file) < 0) {
  100. error("%s: remove: %r", file);
  101. free(data);
  102. return 1;
  103. }
  104. out = file;
  105. }
  106. if((fd = create(out, OWRITE, mode)) < 0){
  107. error("%s: create: %r", out);
  108. free(data);
  109. return 1;
  110. }
  111. if(write(fd, data, length) != length){
  112. error("%s: write: %r", out);
  113. close(fd);
  114. free(data);
  115. return 1;
  116. }
  117. close(fd);
  118. free(data);
  119. return 0;
  120. }
  121. void
  122. main(int argc, char* argv[])
  123. {
  124. int r;
  125. char *p;
  126. p = nil;
  127. ARGBEGIN{
  128. default:
  129. usage();
  130. break;
  131. case 'o':
  132. p = ARGF();
  133. if(p == nil)
  134. usage();
  135. break;
  136. }ARGEND;
  137. switch(argc){
  138. case 0:
  139. usage();
  140. return;
  141. case 1:
  142. if(p != nil){
  143. r = strip(*argv, p);
  144. break;
  145. }
  146. /*FALLTHROUGH*/
  147. default:
  148. r = 0;
  149. while(argc > 0){
  150. r |= strip(*argv, nil);
  151. argc--;
  152. argv++;
  153. }
  154. break;
  155. }
  156. if(r)
  157. exits("error");
  158. exits(0);
  159. }