blob: 8787654b5c3836815a96de28bb1e91503d3fe76b [file] [log] [blame]
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07001// Copyright (c) 2018, Google Inc.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
David Benjaminece1f862023-04-24 16:14:08 -040015//go:build ignore
16
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070017// This program takes a file containing newline-separated symbols, and generates
18// boringssl_prefix_symbols.h, boringssl_prefix_symbols_asm.h, and
19// boringssl_prefix_symbols_nasm.inc. These header files can be used to build
20// BoringSSL with a prefix for all symbols in order to avoid symbol name
21// conflicts when linking a project with multiple copies of BoringSSL; see
22// BUILDING.md for more details.
David Benjamin54b04fd2023-01-29 11:56:25 -050023package main
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070024
25// TODO(joshlf): For platforms which support it, use '#pragma redefine_extname'
26// instead of a custom macro. This avoids the need for a custom macro, but also
27// ensures that our renaming won't conflict with symbols defined and used by our
28// consumers (the "HMAC" problem). An example of this approach can be seen in
29// IllumOS' fork of OpenSSL:
30// https://github.com/joyent/illumos-extra/blob/master/openssl1x/sunw_prefix.h
31
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070032import (
33 "bufio"
34 "flag"
35 "fmt"
36 "os"
37 "path/filepath"
38 "strings"
39)
40
41var out = flag.String("out", ".", "Path to a directory where the outputs will be written")
42
43// Read newline-separated symbols from a file, ignoring any comments started
44// with '#'.
45func readSymbols(path string) ([]string, error) {
46 f, err := os.Open(path)
47 if err != nil {
48 return nil, err
49 }
50 defer f.Close()
51 scanner := bufio.NewScanner(f)
52 var ret []string
53 for scanner.Scan() {
54 line := scanner.Text()
55 if idx := strings.IndexByte(line, '#'); idx >= 0 {
56 line = line[:idx]
57 }
58 line = strings.TrimSpace(line)
59 if len(line) == 0 {
60 continue
61 }
62 ret = append(ret, line)
63 }
64 if err := scanner.Err(); err != nil {
65 return nil, err
66 }
67 return ret, nil
68}
69
70func writeCHeader(symbols []string, path string) error {
71 f, err := os.Create(path)
72 if err != nil {
73 return err
74 }
75 defer f.Close()
76
77 if _, err := f.WriteString(`// Copyright (c) 2018, Google Inc.
78//
79// Permission to use, copy, modify, and/or distribute this software for any
80// purpose with or without fee is hereby granted, provided that the above
81// copyright notice and this permission notice appear in all copies.
82//
83// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
84// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
85// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
86// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
87// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
88// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
89// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
90
91// BORINGSSL_ADD_PREFIX pastes two identifiers into one. It performs one
92// iteration of macro expansion on its arguments before pasting.
93#define BORINGSSL_ADD_PREFIX(a, b) BORINGSSL_ADD_PREFIX_INNER(a, b)
94#define BORINGSSL_ADD_PREFIX_INNER(a, b) a ## _ ## b
95
96`); err != nil {
97 return err
98 }
99
100 for _, symbol := range symbols {
101 if _, err := fmt.Fprintf(f, "#define %s BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, %s)\n", symbol, symbol); err != nil {
102 return err
103 }
104 }
105
106 return nil
107}
108
109func writeASMHeader(symbols []string, path string) error {
110 f, err := os.Create(path)
111 if err != nil {
112 return err
113 }
114 defer f.Close()
115
116 if _, err := f.WriteString(`// Copyright (c) 2018, Google Inc.
117//
118// Permission to use, copy, modify, and/or distribute this software for any
119// purpose with or without fee is hereby granted, provided that the above
120// copyright notice and this permission notice appear in all copies.
121//
122// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
123// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
124// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
125// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
126// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
127// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
128// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
129
130#if !defined(__APPLE__)
131#include <boringssl_prefix_symbols.h>
132#else
133// On iOS and macOS, we need to treat assembly symbols differently from other
134// symbols. The linker expects symbols to be prefixed with an underscore.
135// Perlasm thus generates symbol with this underscore applied. Our macros must,
136// in turn, incorporate it.
137#define BORINGSSL_ADD_PREFIX_MAC_ASM(a, b) BORINGSSL_ADD_PREFIX_INNER_MAC_ASM(a, b)
138#define BORINGSSL_ADD_PREFIX_INNER_MAC_ASM(a, b) _ ## a ## _ ## b
139
140`); err != nil {
141 return err
142 }
143
144 for _, symbol := range symbols {
145 if _, err := fmt.Fprintf(f, "#define _%s BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, %s)\n", symbol, symbol); err != nil {
146 return err
147 }
148 }
149
150 _, err = fmt.Fprintf(f, "#endif\n")
151 return nil
152}
153
154func writeNASMHeader(symbols []string, path string) error {
155 f, err := os.Create(path)
156 if err != nil {
157 return err
158 }
159 defer f.Close()
160
161 // NASM uses a different syntax from the C preprocessor.
162 if _, err := f.WriteString(`; Copyright (c) 2018, Google Inc.
163;
164; Permission to use, copy, modify, and/or distribute this software for any
165; purpose with or without fee is hereby granted, provided that the above
166; copyright notice and this permission notice appear in all copies.
167;
168; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
169; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
170; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
171; SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
172; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
173; OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
174; CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
175
David Benjamin8c23d3a2018-11-25 15:58:02 -0600176; 32-bit Windows adds underscores to C functions, while 64-bit Windows does not.
177%ifidn __OUTPUT_FORMAT__, win32
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -0700178`); err != nil {
179 return err
180 }
181
182 for _, symbol := range symbols {
David Benjamin8c23d3a2018-11-25 15:58:02 -0600183 if _, err := fmt.Fprintf(f, "%%xdefine _%s _ %%+ BORINGSSL_PREFIX %%+ _%s\n", symbol, symbol); err != nil {
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -0700184 return err
185 }
186 }
187
David Benjamin8c23d3a2018-11-25 15:58:02 -0600188 if _, err := fmt.Fprintf(f, "%%else\n"); err != nil {
189 return err
190 }
191
192 for _, symbol := range symbols {
193 if _, err := fmt.Fprintf(f, "%%xdefine %s BORINGSSL_PREFIX %%+ _%s\n", symbol, symbol); err != nil {
194 return err
195 }
196 }
197
198 if _, err := fmt.Fprintf(f, "%%endif\n"); err != nil {
199 return err
200 }
201
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -0700202 return nil
203}
204
205func main() {
206 flag.Parse()
207 if flag.NArg() != 1 {
208 fmt.Fprintf(os.Stderr, "Usage: %s [-out OUT] SYMBOLS\n", os.Args[0])
209 os.Exit(1)
210 }
211
212 symbols, err := readSymbols(flag.Arg(0))
213 if err != nil {
214 fmt.Fprintf(os.Stderr, "Error reading symbols: %s\n", err)
215 os.Exit(1)
216 }
217
218 if err := writeCHeader(symbols, filepath.Join(*out, "boringssl_prefix_symbols.h")); err != nil {
219 fmt.Fprintf(os.Stderr, "Error writing boringssl_prefix_symbols.h: %s\n", err)
220 os.Exit(1)
221 }
222
223 if err := writeASMHeader(symbols, filepath.Join(*out, "boringssl_prefix_symbols_asm.h")); err != nil {
224 fmt.Fprintf(os.Stderr, "Error writing boringssl_prefix_symbols_asm.h: %s\n", err)
225 os.Exit(1)
226 }
227
228 if err := writeNASMHeader(symbols, filepath.Join(*out, "boringssl_prefix_symbols_nasm.inc")); err != nil {
229 fmt.Fprintf(os.Stderr, "Error writing boringssl_prefix_symbols_nasm.inc: %s\n", err)
230 os.Exit(1)
231 }
232
233}