]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/contrib/dev/ath/public/wackelf.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / contrib / dev / ath / public / wackelf.c
1 /*-
2  * Copyright (c) 2006 Sam Leffler, Errno Consulting
3  * Copyright (c) 2006 Atheros Communications, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted
7  * provided that the following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following NO
10  *    ''WARRANTY'' disclaimer below (''Disclaimer''), without
11  *    modification.
12  * 2. Redistributions in binary form must reproduce at minimum a
13  *    disclaimer similar to the Disclaimer below and any redistribution
14  *    must be conditioned upon including a substantially similar
15  *    Disclaimer requirement for further binary redistribution.
16  * 3. Neither the names of the above-listed copyright holders nor the
17  *    names of any contributors may be used to endorse or promote
18  *    product derived from this software without specific prior written
19  *    permission.
20  *
21  * NO WARRANTY
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
25  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
27  * FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGES.
34  *
35  * $Id: //depot/sw/branches/sam_hal/public/wackelf.c#3 $
36  */
37
38 /*
39  * Program to zap flags field in the ELF header of an object
40  * file so that it appears to use VFP soft floating point.
41  * This is done because there is no standard way to specify
42  * this on the command line to gcc/binutils.
43  *
44  * Derived from code by Olivier Houchard <cognet@freebsd.org>
45  */
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <elf.h>
49 #include <fcntl.h>
50 #include <err.h>
51
52 #ifdef __linux__
53 #include <endian.h>
54 #include <byteswap.h>
55 #define _LITTLE_ENDIAN  __LITTLE_ENDIAN
56 #define _BIG_ENDIAN     __BIG_ENDIAN
57 #if __BYTE_ORDER == __LITTLE_ENDIAN
58 #define htobe16(x)      __bswap_16((x))
59 #define htobe32(x)      __bswap_32((x))
60 #define htole16(x)      ((uint16_t)(x))
61 #define htole32(x)      ((uint32_t)(x))
62 #else /* _BYTE_ORDER != _LITTLE_ENDIAN */
63 #define htobe16(x)      ((uint16_t)(x))
64 #define htobe32(x)      ((uint32_t)(x))
65 #define htole16(x)      __bswap_16((x))
66 #define htole32(x)      __bswap_32((x))
67 #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
68 #else
69 #include <sys/endian.h>
70 #endif
71
72 int
73 main(int argc, char *argv[])
74 {
75         int fd, endian, oflags;
76         int format = 0x400;             /* default to VFP */
77         Elf32_Ehdr ehdr;
78
79         if (argc > 2) {
80                 if (strcmp(argv[1], "-fpa") == 0) {
81                         format = 0x200;
82                         argc--, argv++;
83                 } else if (strcmp(argv[1], "-vfp") == 0) {
84                         format = 0x400;
85                         argc--, argv++;
86                 } else if (strcmp(argv[1], "-none") == 0) {
87                         format = 0;
88                         argc--, argv++;
89                 }
90         }
91         if (argc != 2) {
92                 fprintf(stderr, "usage: %s [-fpa|-vfp|-none] file\n", argv[0]);
93                 exit(-1);
94         }
95         fd = open(argv[1], O_RDWR);
96         if (fd < 0)
97                 err(1, "could not open %s", argv[1]);
98         if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
99                 err(1, "could not read the ELF header");
100         if (ehdr.e_machine == htole16(EM_ARM))
101                 endian = _LITTLE_ENDIAN;
102         else if (ehdr.e_machine == htobe16(EM_ARM))
103                 endian = _BIG_ENDIAN;
104         else
105                 errx(1, "not an ARM ELF object (machine 0x%x)", ehdr.e_machine);
106         oflags = ehdr.e_flags;
107         if (endian == _BIG_ENDIAN) {
108                 ehdr.e_flags &= ~htobe32(0x600); /* Remove FPA Soft float */
109                 ehdr.e_flags |= htobe32(format); /* VFP Soft Float */
110         } else {
111                 ehdr.e_flags &= ~htole32(0x600); /* Remove FPA Soft float */
112                 ehdr.e_flags |= htole32(format); /* VFP Soft Float */
113         }
114         printf("%s: e_flags 0x%x => 0x%x\n", argv[1], oflags, ehdr.e_flags);
115         if (lseek(fd, (off_t) 0, SEEK_SET) != 0)
116                 err(1, "lseek");
117         if (write(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
118                 err(1, "yow, elf header write failed");
119         close(fd);
120         return 0;
121 }