1 // Copyright (c) 2014, 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 15 // This package generates chacha_vec_arm.S from chacha_vec.c. 16 package main 17 18 import ( 19 "bufio" 20 "bytes" 21 "os" 22 "os/exec" 23 "strings" 24 ) 25 26 const defaultCompiler = "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc" 27 28 func main() { 29 compiler := defaultCompiler 30 if len(os.Args) > 1 { 31 compiler = os.Args[1] 32 } 33 34 args := []string{ 35 "-O3", 36 "-mcpu=cortex-a8", 37 "-mfpu=neon", 38 "-fpic", 39 "-DASM_GEN", 40 "-I", "../../include", 41 "-S", "chacha_vec.c", 42 "-o", "-", 43 } 44 45 output, err := os.OpenFile("chacha_vec_arm.S", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) 46 if err != nil { 47 panic(err) 48 } 49 defer output.Close() 50 51 output.WriteString(preamble) 52 output.WriteString(compiler) 53 output.WriteString(" ") 54 output.WriteString(strings.Join(args, " ")) 55 output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n\n") 56 57 cmd := exec.Command(compiler, args...) 58 cmd.Stderr = os.Stderr 59 asm, err := cmd.StdoutPipe() 60 if err != nil { 61 panic(err) 62 } 63 if err := cmd.Start(); err != nil { 64 panic(err) 65 } 66 67 attr28 := []byte(".eabi_attribute 28,") 68 globalDirective := []byte(".global\t") 69 newLine := []byte("\n") 70 attr28Handled := false 71 72 scanner := bufio.NewScanner(asm) 73 for scanner.Scan() { 74 line := scanner.Bytes() 75 76 if bytes.Contains(line, attr28) { 77 output.WriteString(attr28Block) 78 attr28Handled = true 79 continue 80 } 81 82 output.Write(line) 83 output.Write(newLine) 84 85 if i := bytes.Index(line, globalDirective); i >= 0 { 86 output.Write(line[:i]) 87 output.WriteString(".hidden\t") 88 output.Write(line[i+len(globalDirective):]) 89 output.Write(newLine) 90 } 91 } 92 93 if err := scanner.Err(); err != nil { 94 panic(err) 95 } 96 97 if !attr28Handled { 98 panic("EABI attribute 28 not seen in processing") 99 } 100 101 if err := cmd.Wait(); err != nil { 102 panic(err) 103 } 104 105 output.WriteString(trailer) 106 } 107 108 const preamble = `# Copyright (c) 2014, Google Inc. 109 # 110 # Permission to use, copy, modify, and/or distribute this software for any 111 # purpose with or without fee is hereby granted, provided that the above 112 # copyright notice and this permission notice appear in all copies. 113 # 114 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 115 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 116 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 117 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 118 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 119 # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 120 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 121 122 # This file contains a pre-compiled version of chacha_vec.c for ARM. This is 123 # needed to support switching on NEON code at runtime. If the whole of OpenSSL 124 # were to be compiled with the needed flags to build chacha_vec.c, then it 125 # wouldn't be possible to run on non-NEON systems. 126 # 127 # This file was generated by chacha_vec_arm_generate.go using the following 128 # compiler command: 129 # 130 # ` 131 132 const attr28Block = ` 133 # EABI attribute 28 sets whether VFP register arguments were used to build this 134 # file. If object files are inconsistent on this point, the linker will refuse 135 # to link them. Thus we report whatever the compiler expects since we don't use 136 # VFP arguments. 137 138 #if defined(__ARM_PCS_VFP) 139 .eabi_attribute 28, 1 140 #else 141 .eabi_attribute 28, 0 142 #endif 143 144 ` 145 146 const trailer = ` 147 #endif /* !OPENSSL_NO_ASM */ 148 ` 149