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