Joshua Liebow-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 1 | // 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 Benjamin | ece1f86 | 2023-04-24 16:14:08 -0400 | [diff] [blame] | 15 | //go:build ignore |
| 16 | |
Joshua Liebow-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 17 | // 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 Benjamin | 54b04fd | 2023-01-29 11:56:25 -0500 | [diff] [blame] | 23 | package main |
Joshua Liebow-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 24 | |
| 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-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 32 | import ( |
| 33 | "bufio" |
| 34 | "flag" |
| 35 | "fmt" |
| 36 | "os" |
| 37 | "path/filepath" |
| 38 | "strings" |
| 39 | ) |
| 40 | |
| 41 | var 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 '#'. |
| 45 | func 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 | |
| 70 | func 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 | |
| 109 | func 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 | |
| 154 | func 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 Benjamin | 8c23d3a | 2018-11-25 15:58:02 -0600 | [diff] [blame] | 176 | ; 32-bit Windows adds underscores to C functions, while 64-bit Windows does not. |
| 177 | %ifidn __OUTPUT_FORMAT__, win32 |
Joshua Liebow-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 178 | `); err != nil { |
| 179 | return err |
| 180 | } |
| 181 | |
| 182 | for _, symbol := range symbols { |
David Benjamin | 8c23d3a | 2018-11-25 15:58:02 -0600 | [diff] [blame] | 183 | if _, err := fmt.Fprintf(f, "%%xdefine _%s _ %%+ BORINGSSL_PREFIX %%+ _%s\n", symbol, symbol); err != nil { |
Joshua Liebow-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 184 | return err |
| 185 | } |
| 186 | } |
| 187 | |
David Benjamin | 8c23d3a | 2018-11-25 15:58:02 -0600 | [diff] [blame] | 188 | 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-Feeser | 8c7c635 | 2018-08-26 18:53:36 -0700 | [diff] [blame] | 202 | return nil |
| 203 | } |
| 204 | |
| 205 | func 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 | } |