github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/crypto/internal/boring/build-goboring.sh (about) 1 #!/bin/bash 2 # Copyright 2020 The Go Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style 4 # license that can be found in the LICENSE file. 5 6 # Do not run directly; run build.sh, which runs this in Docker. 7 # This script builds goboringcrypto's syso, after boringssl has been built. 8 9 export TERM=dumb 10 11 set -e 12 set -x 13 id 14 date 15 export LANG=C 16 unset LANGUAGE 17 18 case $(uname -m) in 19 x86_64) export GOARCH=amd64 ;; 20 aarch64) export GOARCH=arm64 ;; 21 *) 22 echo 'unknown uname -m:' $(uname -m) >&2 23 exit 2 24 esac 25 26 export CGO_ENABLED=0 27 28 # Build and run test C++ program to make sure goboringcrypto.h matches openssl/*.h. 29 # Also collect list of checked symbols in syms.txt 30 set -e 31 cd /boring/godriver 32 cat >goboringcrypto.cc <<'EOF' 33 #include <cassert> 34 #include "goboringcrypto0.h" 35 #include "goboringcrypto1.h" 36 #define check_size(t) if(sizeof(t) != sizeof(GO_ ## t)) {printf("sizeof(" #t ")=%d, but sizeof(GO_" #t ")=%d\n", (int)sizeof(t), (int)sizeof(GO_ ## t)); ret=1;} 37 #define check_func(f) { auto x = f; x = _goboringcrypto_ ## f ; } 38 #define check_value(n, v) if(n != v) {printf(#n "=%d, but goboringcrypto.h defines it as %d\n", (int)n, (int)v); ret=1;} 39 int main() { 40 int ret = 0; 41 #include "goboringcrypto.x" 42 return ret; 43 } 44 EOF 45 46 cat >boringx.awk <<'EOF' 47 BEGIN { 48 exitcode = 0 49 } 50 51 # Ignore comments, #includes, blank lines. 52 /^\/\// || /^#/ || NF == 0 { next } 53 54 # Ignore unchecked declarations. 55 /\/\*unchecked/ { next } 56 57 # Check enum values. 58 !enum && $1 == "enum" && $NF == "{" { 59 enum = 1 60 next 61 } 62 enum && $1 == "};" { 63 enum = 0 64 next 65 } 66 enum && NF == 3 && $2 == "=" { 67 name = $1 68 sub(/^GO_/, "", name) 69 val = $3 70 sub(/,$/, "", val) 71 print "check_value(" name ", " val ")" > "goboringcrypto.x" 72 next 73 } 74 enum { 75 print FILENAME ":" NR ": unexpected line in enum: " $0 > "/dev/stderr" 76 exitcode = 1 77 next 78 } 79 80 # Check struct sizes. 81 /^typedef struct / && $NF ~ /^GO_/ { 82 name = $NF 83 sub(/^GO_/, "", name) 84 sub(/;$/, "", name) 85 print "check_size(" name ")" > "goboringcrypto.x" 86 next 87 } 88 89 # Check function prototypes. 90 /^(const )?[^ ]+ \**_goboringcrypto_.*\(/ { 91 name = $2 92 if($1 == "const") 93 name = $3 94 sub(/^\**_goboringcrypto_/, "", name) 95 sub(/\(.*/, "", name) 96 print "check_func(" name ")" > "goboringcrypto.x" 97 print name > "syms.txt" 98 next 99 } 100 101 { 102 print FILENAME ":" NR ": unexpected line: " $0 > "/dev/stderr" 103 exitcode = 1 104 } 105 106 END { 107 exit exitcode 108 } 109 EOF 110 111 cat >boringh.awk <<'EOF' 112 /^\/\/ #include/ {sub(/\/\//, ""); print > "goboringcrypto0.h"; next} 113 /typedef struct|enum ([a-z_]+ )?{|^[ \t]/ {print >"goboringcrypto1.h";next} 114 {gsub(/GO_/, ""); gsub(/enum go_/, "enum "); print >"goboringcrypto1.h"} 115 EOF 116 117 awk -f boringx.awk goboringcrypto.h # writes goboringcrypto.x 118 awk -f boringh.awk goboringcrypto.h # writes goboringcrypto[01].h 119 120 ls -l ../boringssl/include 121 clang++ -std=c++11 -fPIC -I../boringssl/include -O2 -o a.out goboringcrypto.cc 122 ./a.out || exit 2 123 124 # clang implements u128 % u128 -> u128 by calling __umodti3, 125 # which is in libgcc. To make the result self-contained even if linking 126 # against a different compiler version, link our own __umodti3 into the syso. 127 # This one is specialized so it only expects divisors below 2^64, 128 # which is all BoringCrypto uses. (Otherwise it will seg fault.) 129 cat >umod-amd64.s <<'EOF' 130 # tu_int __umodti3(tu_int x, tu_int y) 131 # x is rsi:rdi, y is rcx:rdx, return result is rdx:rax. 132 .globl __umodti3 133 __umodti3: 134 # specialized to u128 % u64, so verify that 135 test %rcx,%rcx 136 jne 1f 137 138 # save divisor 139 movq %rdx, %r8 140 141 # reduce top 64 bits mod divisor 142 movq %rsi, %rax 143 xorl %edx, %edx 144 divq %r8 145 146 # reduce full 128-bit mod divisor 147 # quotient fits in 64 bits because top 64 bits have been reduced < divisor. 148 # (even though we only care about the remainder, divq also computes 149 # the quotient, and it will trap if the quotient is too large.) 150 movq %rdi, %rax 151 divq %r8 152 153 # expand remainder to 128 for return 154 movq %rdx, %rax 155 xorl %edx, %edx 156 ret 157 158 1: 159 # crash - only want 64-bit divisor 160 xorl %ecx, %ecx 161 movl %ecx, 0(%ecx) 162 jmp 1b 163 164 .section .note.GNU-stack,"",@progbits 165 EOF 166 167 cat >umod-arm64.c <<'EOF' 168 typedef unsigned int u128 __attribute__((mode(TI))); 169 170 static u128 div(u128 x, u128 y, u128 *rp) { 171 int n = 0; 172 while((y>>(128-1)) != 1 && y < x) { 173 y<<=1; 174 n++; 175 } 176 u128 q = 0; 177 for(;; n--, y>>=1, q<<=1) { 178 if(x>=y) { 179 x -= y; 180 q |= 1; 181 } 182 if(n == 0) 183 break; 184 } 185 if(rp) 186 *rp = x; 187 return q; 188 } 189 190 u128 __umodti3(u128 x, u128 y) { 191 u128 r; 192 div(x, y, &r); 193 return r; 194 } 195 196 u128 __udivti3(u128 x, u128 y) { 197 return div(x, y, 0); 198 } 199 EOF 200 201 extra="" 202 case $GOARCH in 203 amd64) 204 cp umod-amd64.s umod.s 205 clang -c -o umod.o umod.s 206 extra=umod.o 207 ;; 208 arm64) 209 cp umod-arm64.c umod.c 210 clang -c -o umod.o umod.c 211 extra=umod.o 212 ;; 213 esac 214 215 # Prepare copy of libcrypto.a with only the checked functions renamed and exported. 216 # All other symbols are left alone and hidden. 217 echo BORINGSSL_bcm_power_on_self_test >>syms.txt 218 awk '{print "_goboringcrypto_" $0 }' syms.txt >globals.txt 219 awk '{print $0 " _goboringcrypto_" $0 }' syms.txt >renames.txt 220 objcopy --globalize-symbol=BORINGSSL_bcm_power_on_self_test \ 221 ../boringssl/build/crypto/libcrypto.a libcrypto.a 222 223 # Link together bcm.o and libcrypto.a into a single object. 224 ld -r -nostdlib --whole-archive -o goboringcrypto.o libcrypto.a $extra 225 226 echo __umodti3 _goboringcrypto___umodti3 >>renames.txt 227 echo __udivti3 _goboringcrypto___udivti3 >>renames.txt 228 objcopy --remove-section=.llvm_addrsig goboringcrypto.o goboringcrypto1.o # b/179161016 229 objcopy --redefine-syms=renames.txt goboringcrypto1.o goboringcrypto2.o 230 objcopy --keep-global-symbols=globals.txt --strip-unneeded goboringcrypto2.o goboringcrypto_linux_$GOARCH.syso 231 232 # Done! 233 ls -l goboringcrypto_linux_$GOARCH.syso