1// Copyright 2018 The BoringSSL Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15//go:build ignore 16 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. 23package main 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 32import ( 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 2018 The BoringSSL Authors 78// 79// Licensed under the Apache License, Version 2.0 (the "License"); 80// you may not use this file except in compliance with the License. 81// You may obtain a copy of the License at 82// 83// https://www.apache.org/licenses/LICENSE-2.0 84// 85// Unless required by applicable law or agreed to in writing, software 86// distributed under the License is distributed on an "AS IS" BASIS, 87// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 88// See the License for the specific language governing permissions and 89// limitations under the License. 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 2018 The BoringSSL Authors 117// 118// Licensed under the Apache License, Version 2.0 (the "License"); 119// you may not use this file except in compliance with the License. 120// You may obtain a copy of the License at 121// 122// https://www.apache.org/licenses/LICENSE-2.0 123// 124// Unless required by applicable law or agreed to in writing, software 125// distributed under the License is distributed on an "AS IS" BASIS, 126// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127// See the License for the specific language governing permissions and 128// limitations under the License. 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 2018 The BoringSSL Authors 163; 164; Licensed under the Apache License, Version 2.0 (the "License"); 165; you may not use this file except in compliance with the License. 166; You may obtain a copy of the License at 167; 168; https://www.apache.org/licenses/LICENSE-2.0 169; 170; Unless required by applicable law or agreed to in writing, software 171; distributed under the License is distributed on an "AS IS" BASIS, 172; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 173; See the License for the specific language governing permissions and 174; limitations under the License. 175 176; 32-bit Windows adds underscores to C functions, while 64-bit Windows does not. 177%ifidn __OUTPUT_FORMAT__, win32 178`); err != nil { 179 return err 180 } 181 182 for _, symbol := range symbols { 183 if _, err := fmt.Fprintf(f, "%%xdefine _%s _ %%+ BORINGSSL_PREFIX %%+ _%s\n", symbol, symbol); err != nil { 184 return err 185 } 186 } 187 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 202 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} 234