strip.c 2.4 KB

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