revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / atheros5000 / hal / public / wackelf.c
blobc0473cdcae2b0df7aa3b17b5a07c824e58b770d0
1 /*
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * $Id$
21 * Program to zap flags field in the ELF header of an object
22 * file so that it appears to use VFP soft floating point.
23 * This is done because there is no standard way to specify
24 * this on the command line to gcc/binutils.
26 * Derived from code by Olivier Houchard <cognet@freebsd.org>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <elf.h>
31 #include <fcntl.h>
32 #include <err.h>
34 #ifdef __linux__
35 #include <endian.h>
36 #include <byteswap.h>
37 #define _LITTLE_ENDIAN __LITTLE_ENDIAN
38 #define _BIG_ENDIAN __BIG_ENDIAN
39 #if __BYTE_ORDER == __LITTLE_ENDIAN
40 #define htobe16(x) __bswap_16((x))
41 #define htobe32(x) __bswap_32((x))
42 #define htole16(x) ((uint16_t)(x))
43 #define htole32(x) ((uint32_t)(x))
44 #else /* _BYTE_ORDER != _LITTLE_ENDIAN */
45 #define htobe16(x) ((uint16_t)(x))
46 #define htobe32(x) ((uint32_t)(x))
47 #define htole16(x) __bswap_16((x))
48 #define htole32(x) __bswap_32((x))
49 #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
50 #else
51 #include <sys/endian.h>
52 #endif
54 int
55 main(int argc, char *argv[])
57 int fd, endian, oflags;
58 int format = 0x400; /* default to VFP */
59 Elf32_Ehdr ehdr;
61 if (argc > 2) {
62 if (strcmp(argv[1], "-fpa") == 0) {
63 format = 0x200;
64 argc--, argv++;
65 } else if (strcmp(argv[1], "-vfp") == 0) {
66 format = 0x400;
67 argc--, argv++;
68 } else if (strcmp(argv[1], "-none") == 0) {
69 format = 0;
70 argc--, argv++;
73 if (argc != 2) {
74 fprintf(stderr, "usage: %s [-fpa|-vfp|-none] file\n", argv[0]);
75 exit(-1);
77 fd = open(argv[1], O_RDWR);
78 if (fd < 0)
79 err(1, "could not open %s", argv[1]);
80 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
81 err(1, "could not read the ELF header");
82 if (ehdr.e_machine == htole16(EM_ARM))
83 endian = _LITTLE_ENDIAN;
84 else if (ehdr.e_machine == htobe16(EM_ARM))
85 endian = _BIG_ENDIAN;
86 else
87 errx(1, "not an ARM ELF object (machine 0x%x)", ehdr.e_machine);
88 oflags = ehdr.e_flags;
89 if (endian == _BIG_ENDIAN) {
90 ehdr.e_flags &= ~htobe32(0x600); /* Remove FPA Soft float */
91 ehdr.e_flags |= htobe32(format); /* VFP Soft Float */
92 } else {
93 ehdr.e_flags &= ~htole32(0x600); /* Remove FPA Soft float */
94 ehdr.e_flags |= htole32(format); /* VFP Soft Float */
96 printf("%s: e_flags 0x%x => 0x%x\n", argv[1], oflags, ehdr.e_flags);
97 if (lseek(fd, (off_t) 0, SEEK_SET) != 0)
98 err(1, "lseek");
99 if (write(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
100 err(1, "yow, elf header write failed");
101 close(fd);
102 return 0;