brandelf.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*-
  2. * Copyright (c) 1996 Søren Schmidt
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer
  10. * in this position and unchanged.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software withough specific prior written permission
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. * $FreeBSD: src/usr.bin/brandelf/brandelf.c,v 1.16 2000/07/02 03:34:08 imp Exp $
  29. */
  30. #include <elf.h>
  31. #include <fcntl.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include <sys/errno.h>
  37. #include <err.h>
  38. /* These are defined on FreeBSD, but not on Linux */
  39. #ifndef ELFOSABI_SYSV
  40. #define ELFOSABI_SYSV 0
  41. #endif
  42. #ifndef ELFOSABI_LINUX
  43. #define ELFOSABI_LINUX 3
  44. #endif
  45. #ifndef ELFOSABI_HURD
  46. #define ELFOSABI_HURD 4
  47. #endif
  48. #ifndef ELFOSABI_SOLARIS
  49. #define ELFOSABI_SOLARIS 6
  50. #endif
  51. #ifndef ELFOSABI_FREEBSD
  52. #define ELFOSABI_FREEBSD 9
  53. #endif
  54. static int elftype(const char *);
  55. static const char *iselftype(int);
  56. static void printelftypes(void);
  57. static void usage __P((void));
  58. struct ELFtypes {
  59. const char *str;
  60. int value;
  61. };
  62. /* XXX - any more types? */
  63. static struct ELFtypes elftypes[] = {
  64. { "FreeBSD", ELFOSABI_FREEBSD },
  65. { "Linux", ELFOSABI_LINUX },
  66. { "Solaris", ELFOSABI_SOLARIS },
  67. { "SVR4", ELFOSABI_SYSV }
  68. };
  69. int
  70. main(int argc, char **argv)
  71. {
  72. const char *strtype = "FreeBSD";
  73. int type = ELFOSABI_FREEBSD;
  74. int retval = 0;
  75. int ch, change = 0, verbose = 0, force = 0, listed = 0;
  76. while ((ch = getopt(argc, argv, "f:lt:v")) != -1)
  77. switch (ch) {
  78. case 'f':
  79. if (change)
  80. errx(1, "f option incompatable with t option");
  81. force = 1;
  82. type = atoi(optarg);
  83. if (errno == ERANGE || type < 0 || type > 255) {
  84. warnx("invalid argument to option f: %s",
  85. optarg);
  86. usage();
  87. }
  88. break;
  89. case 'l':
  90. printelftypes();
  91. listed = 1;
  92. break;
  93. case 'v':
  94. verbose = 1;
  95. break;
  96. case 't':
  97. if (force)
  98. errx(1, "t option incompatable with f option");
  99. change = 1;
  100. strtype = optarg;
  101. break;
  102. default:
  103. usage();
  104. }
  105. argc -= optind;
  106. argv += optind;
  107. if (!argc) {
  108. if (listed)
  109. exit(0);
  110. else {
  111. warnx("no file(s) specified");
  112. usage();
  113. }
  114. }
  115. if (!force && (type = elftype(strtype)) == -1) {
  116. warnx("invalid ELF type '%s'", strtype);
  117. printelftypes();
  118. usage();
  119. }
  120. while (argc) {
  121. int fd;
  122. char buffer[EI_NIDENT];
  123. if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) {
  124. warn("error opening file %s", argv[0]);
  125. retval = 1;
  126. goto fail;
  127. }
  128. if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) {
  129. warnx("file '%s' too short", argv[0]);
  130. retval = 1;
  131. goto fail;
  132. }
  133. if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 ||
  134. buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) {
  135. warnx("file '%s' is not ELF format", argv[0]);
  136. retval = 1;
  137. goto fail;
  138. }
  139. if (!change && !force) {
  140. fprintf(stdout,
  141. "File '%s' is of brand '%s' (%u).\n",
  142. argv[0], iselftype(buffer[EI_OSABI]),
  143. buffer[EI_OSABI]);
  144. if (!iselftype(type)) {
  145. warnx("ELF ABI Brand '%u' is unknown",
  146. type);
  147. printelftypes();
  148. }
  149. }
  150. else {
  151. buffer[EI_OSABI] = type;
  152. lseek(fd, 0, SEEK_SET);
  153. if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) {
  154. warn("error writing %s %d", argv[0], fd);
  155. retval = 1;
  156. goto fail;
  157. }
  158. }
  159. fail:
  160. close(fd);
  161. argc--;
  162. argv++;
  163. }
  164. return retval;
  165. }
  166. static void
  167. usage()
  168. {
  169. fprintf(stderr, "usage: brandelf [-f ELF ABI number] [-v] [-l] [-t string] file ...\n");
  170. exit(1);
  171. }
  172. static const char *
  173. iselftype(int elftype)
  174. {
  175. int elfwalk;
  176. for (elfwalk = 0;
  177. elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
  178. elfwalk++)
  179. if (elftype == elftypes[elfwalk].value)
  180. return elftypes[elfwalk].str;
  181. return 0;
  182. }
  183. static int
  184. elftype(const char *elfstrtype)
  185. {
  186. int elfwalk;
  187. for (elfwalk = 0;
  188. elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
  189. elfwalk++)
  190. if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0)
  191. return elftypes[elfwalk].value;
  192. return -1;
  193. }
  194. static void
  195. printelftypes()
  196. {
  197. int elfwalk;
  198. fprintf(stderr, "known ELF types are: ");
  199. for (elfwalk = 0;
  200. elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
  201. elfwalk++)
  202. fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str,
  203. elftypes[elfwalk].value);
  204. fprintf(stderr, "\n");
  205. }