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 19package main 20 21import ( 22 "bufio" 23 "bytes" 24 "os" 25 "os/exec" 26 "strings" 27) 28 29const defaultCompiler = "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc" 30 31func 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 112const 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 136const 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 150const trailer = ` 151#endif /* __arm__ */ 152#endif /* !OPENSSL_NO_ASM */ 153` 154