make_prefix_headers.go 7.8 KB

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