Not only is the Internet dead, it's starting to smell really bad.:2019年07月下旬

2019/07/20(Sat)

[GCC] よくあるしっぱい

コードななめ読みでifdef追加して__sparcv9と__sparc_v9__の挙動の違いにハマって1時間ほど潰れた気分はどうだ?

まぁ知ってる人は知ってるだろうけど、初心者Sun向けに解説書いておくと、__sparcv9ってのはSUNWpro *1というコンパイラの事前定義マクロ。

そんで__sparc_v9__ってのはgccの事前定義マクロなんだけどこいつはご丁寧にSUNWpro互換の事前定義マクロも吐くので__sparcv9もプリプロセッサは処理する。

なのでgcc環境では名前がよく似ているので両者を混同してしまいがちなんだが、じつはこいつら意味は違うので迂闊に書き間違えると死ぬ。

$ echo __sparcv9 | /usr/tooldir/bin/sparc64--netbsd-gcc -E  -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
1

$ echo __sparc_v9__ | /usr/tooldir/bin/sparc64--netbsd-gcc -E  -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
1

と64bitコード吐いてる間は同じなんだけど、-m32スイッチつけて32bitコード吐かせようとすると

$ echo __sparcv9 | /usr/tooldir/bin/sparc64--netbsd-gcc -m32 -E  -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
__sparcv9

$ echo __sparc_v9__ | /usr/tooldir/bin/sparc64--netbsd-gcc -m32 -E  -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
1

はい、今死んだ今死んだよ君!

ということでgccでsparc or sparc64のifdef切るには__sparc_v9__ではなく__sparc__ + __arch64__を使えというお話。

$ echo __arch64__ | /usr/tooldir/bin/sparc64--netbsd-gcc -E  -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
1

$ echo __arch64__ | /usr/tooldir/bin/sparc64--netbsd-gcc -m32 -E  -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
__arch64__
*1:商品名だとアホみたいにブランド名変え続けてたので(Oracle Developer Studio←Sun Studio←Sun ONE Studio←Forte Developer←Sun Workshop←SunSoft Workshop←SPARCworks)、混乱しないように最後まで変わらなかったSVR4パッケージ名でみんな呼んでるはず…だよね?

2019/07/21(Sun)

[オープンソース] git cherry-pickでいともたやすく行われるライセンス汚染

先日からこのチラシの裏で実況しとる通りオレオレN6のOpenSSLメンテを楽にするためgit subtree化しつつ

という作業をしたんだが、これまじめに考えると

という問題をはらんでることに気づいてしまった。

これOpenSSLの開発者自身が1.0.2枝にプルアップしのであればパッチ貢献者がライセンス変更に同意したと見なしてもいいんだろうけど、ワイ個人が勝手に持ってくるってパターンではアウトだよなぁ、まさかパッチだけはデュアルライセンスなんて都合のいい解釈は通らねえし。

ワイ自身はOpenBSDみたいにAPL2.0断固反対ではないけど、置き場所をcrypto/external/bsdからcrypto/expernal/apache2に移さんとならんのがアレ。

[オレオレN6] まだOpenSSLいじってる

前記事でOpenSSL1.1.0以降はAPL2.0と書いてしまったが、まだリリースされてない3.0からAPL2.0に切替わるので、今リリースされてるブツはまだBSDLであった *1

それと作業も残り少ない段階になって残念なことに気づいてしまったんだが、OpenSSL-1.0.2のEOLは2019/12/31なので半年後にはまた1.1.1化の作業が必要になるのだ、そんなら最初っから1.1.1にしておけばよかったぞはやく教えてよ…

まぁ現在のソースツリー上でのビルドプロセスを理解したしNローカルパッチの要不要の切り分けができてるから、1.1.1化も今回ほど手間はかからんだろうからええけどな。

@MACHINE_CPU=vaxでビルドがこける

なるほど、bn_exp.cのコードでalloca使わないように変更してた件は実行時に-fstack-protectorのガードが働いて死ぬからでなく、警告オプションの-Wstack-protectorにひっかかって-Werrorとのコンボでビルドエラーになるのか。

--- bn_exp.o ---
#   compile  libcrypto/bn_exp.o
/usr/tooldir/bin/vax--netbsdelf-gcc -O1 -fgcse -fstrength-reduce -fgcse-after-reload -std=gnu99  -Werror   -fstack-protector -Wstack-protector   --param ssp-buffer-size=1   --sysroot=/usr/src/obj.vax/destdir.vax -Dlibcrypto -I. -I/usr/src/crypto/external/bsd/openssl/dist/crypto -I/usr/src/crypto/external/bsd/openssl/dist -I/usr/src/crypto/external/bsd/openssl/dist/crypto/asn1 -I/usr/src/crypto/external/bsd/openssl/dist/crypto/evp -I/usr/src/crypto/external/bsd/openssl/dist/crypto/modes -DDSO_DLFCN -DHAVE_DLFCN_H  -D_FORTIFY_SOURCE=2 -c   -I/usr/src/crypto/external/bsd/openssl/dist/crypto/bn /usr/src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c -o bn_exp.o
cc1: warnings being treated as errors
/usr/src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c: In function 'BN_mod_exp_mont_consttime':
/usr/src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c:698: warning: not protecting local variables: variable length buffer
*** [bn_exp.o] Error code 1
nbmake: stopped in /usr/src/crypto/external/bsd/openssl/lib/libcrypto

これNだとamd64なんかではエラーにならんので意識したことなかったな、__builtin_allocaだと抑制されるわけでもなさそうなんだがなーんでエラー出ないんですかねぇ…

該当箇所のコードはこんなん。

#ifdef alloca
    if (powerbufLen < 3072)
        powerbufFree =
            alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
    else
#endif
        if ((powerbufFree =
             (unsigned char *)OPENSSL_malloc(powerbufLen +
                                             MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH))
            == NULL)
        goto err;

ちょいと頭のいいコンパイラならpowerbufLenのとりうる値は最大でわずか3072+64でその程度でスタック踏み抜く可能性はほぼ皆無と判断できそうな気もするけど、問答無用で-Wstack-protectorが発動するもよう。

つーかそもそもこれallocaだったら定数でも出るんだな。

#include <stdio.h>

int
main(void)
{
        alloca(1);
}
$ LANG=C gcc -fstack-protector -Wstack-protector unko.c -o unko
unkox.c: In function 'main':
unkox.c:6:1: warning: stack protector not protecting local variables: variable length buffer [-Wstack-protector]
 main(void)

もうこうちょっと慈悲はないんですかねぇ…

むーgccのコード確認したら、alloca呼んだら無条件でこの警告出るもよう。

  /* Honor stack protection warnings.  */
  if (warn_stack_protect)
    {
      if (cfun->calls_alloca)
        warning (OPT_Wstack_protector,
                 "not protecting local variables: variable length buffer");
      if (has_short_buffer && !crtl->stack_protect_guard)
        warning (OPT_Wstack_protector,
                 "not protecting function: no buffer at least %d bytes long",
                 (int) PARAM_VALUE (PARAM_SSP_BUFFER_SIZE));
    }

まぁチェック条件などで最大値が決まってるとしても実際のスタックサイズはわからんから一律禁止ってことか、vmparam.hのDFLSSIZ/MAXSSIZあたりでなんとかならんのか。

んでコード監査の結果としては、OpenSSLでalloca呼んでるとこはスタック踏み抜くほどのサイズ要求にならんのは前後のコード読めば確定的なので、警告抑制でいいかもう。

diff --git a/crypto/external/bsd/openssl/lib/libcrypto/bn.inc b/crypto/external/bsd/openssl/lib/libcrypto/bn.inc
index 51bda18c54..37fad137ae 100644
--- a/crypto/external/bsd/openssl/lib/libcrypto/bn.inc
+++ b/crypto/external/bsd/openssl/lib/libcrypto/bn.inc
@@ -21,3 +21,5 @@ SRCS += ${BN_SRCS}
 .for cryptosrc in ${BN_SRCS}
 CPPFLAGS.${cryptosrc} = -I${OPENSSLSRC}/crypto/bn
 .endfor
+
+COPTS.bn_exp.c=-Wno-stack-protector
diff --git a/crypto/external/bsd/openssl/lib/libcrypto/engine.inc b/crypto/external/bsd/openssl/lib/libcrypto/engine.inc
index de4d66052e..3718b447f9 100644
--- a/crypto/external/bsd/openssl/lib/libcrypto/engine.inc
+++ b/crypto/external/bsd/openssl/lib/libcrypto/engine.inc
@@ -39,3 +39,5 @@ CRYPTOCPPFLAGS+=-DNEED_CPUID_SETUP
 .for cryptosrc in ${ENGINE_SRCS}
 CPPFLAGS.${cryptosrc} = -I${OPENSSLSRC}/crypto/engine ${CRYPTOCPPFLAGS}
 .endfor
+
+COPTS.e_padlock.c=-Wno-stack-protector

ってもNローカルパッチのようにalloca → malloc+freeしたところでたいした差分ではないんだけども。

@MACHINE_CPU=m68kでビルドがこける

うーんm68kのAESのencrypt/decryptはNだとアセンブラで書かれてるんだけど、N8のソースのままだとビルド通らんな。

#      link  bin/openssl
/usr/tooldir/bin/m68k--netbsdelf-gcc    --sysroot=/usr/src/obj.hp300/destdir.hp300     -o openssl  openssl.o apps.o ecparam.o ec.o pkeyparam.o genpkey.o pkey.o pkeyutl.o ts.o cms.o s_cb.o s_socket.o app_rand.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o x509.o genrsa.o gendsa.o prime.o s_server.o s_client.o speed.o s_time.o version.o sess_id.o srp.o ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o smime.o rand.o engine.o ocsp.o -lssl -lcrypto -lcrypt       -Wl,-rpath-link,/usr/src/obj.hp300/destdir.hp300/lib  -L=/lib
/usr/tooldir/lib/gcc/m68k--netbsdelf/4.5.3/../../../../m68k--netbsdelf/bin/ld: warning: type and size of dynamic symbol `AES_encrypt' are not defined
/usr/tooldir/lib/gcc/m68k--netbsdelf/4.5.3/../../../../m68k--netbsdelf/bin/ld: dynamic variable `AES_encrypt' is zero size
/usr/tooldir/lib/gcc/m68k--netbsdelf/4.5.3/../../../../m68k--netbsdelf/bin/ld: speed.o(.text+0x2972): unresolvable R_68K_32 relocation against symbol `AES_encrypt'
/usr/tooldir/lib/gcc/m68k--netbsdelf/4.5.3/../../../../m68k--netbsdelf/bin/ld: final link failed: Nonrepresentable section on output
collect2: ld returned 1 exit status

エラーログだと

  • AES_encryptに.typeと.sizeが定義されてねえぜ
  • AES_encryptのサイズがゼロだぜ
  • AES_encryptが解決できねえから再配置できねえぜ
  • 存在しないセクションあるからリンク失敗だぜ

ちゅーことでGNU asの.typeと.size疑似命令で明示しろってだけなんだが、N8はこのままリリースされとるってことはbinutilsのバージョンでエラーにはならんのかな。 そんでもHEADにimportされてる1.1.1(crypto/external/bsd/openssl)の方では修正はいってたりよくわからん。

ちなみにその修正もコピペミスでバグってるからオレオレN6ではリンクエラーなのだ、正しくは↓やね。

$ diff -u aes-m68k.S.orig aes-m68k.S
--- aes-m68k.S.orig     2018-03-07 15:55:01.000000000 +0900
+++ aes-m68k.S  2019-07-21 15:12:12.869653900 +0900
@@ -828,7 +828,7 @@

        moveml  %sp@+,%d2-%d7/%a2-%a5
        rts
-       .size   AES_set_decrypt_key, .-AES_set_decrypt_key
+       .size   AES_encrypt, .-AES_encrypt

 | void
 | AES_decrypt(const unsigned char *in,

@MACHINE_CPU=armわからん

うーんarm_arch.hの定義を眺めてるけど 全部同じじゃないですかとしかいいようがないぞ…

# if !defined(__ARM_ARCH__)
#  if defined(__CC_ARM)
#   define __ARM_ARCH__ __TARGET_ARCH_ARM
#   if defined(__BIG_ENDIAN)
#    define __ARMEB__
#   else
#    define __ARMEL__
#   endif
#  elif defined(__GNUC__)
#   if   defined(__aarch64__)
#    define __ARM_ARCH__ 8
#    if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
#     define __ARMEB__
#    else
#     define __ARMEL__
#    endif
  /*
   * Why doesn't gcc define __ARM_ARCH__? Instead it defines
   * bunch of below macros. See all_architectires[] table in
   * gcc/config/arm/arm.c. On a side note it defines
   * __ARMEL__/__ARMEB__ for little-/big-endian.
   */
#   elif defined(__ARM_ARCH)
#    define __ARM_ARCH__ __ARM_ARCH
#   elif defined(__ARM_ARCH_8A__)
#    define __ARM_ARCH__ 8
#   elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)     || \
        defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__)     || \
        defined(__ARM_ARCH_7EM__)
#    define __ARM_ARCH__ 7
#   elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__)     || \
        defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__)     || \
        defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__)    || \
        defined(__ARM_ARCH_6T2__)
#    define __ARM_ARCH__ 6
#   elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__)     || \
        defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__)    || \
        defined(__ARM_ARCH_5TEJ__)
#    define __ARM_ARCH__ 5
#   elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
#    define __ARM_ARCH__ 4
#   else
#    error "unsupported ARM architecture"
#   endif
#  endif
# endif

ゲシュタルト崩壊してきたぞ…

そんでワイも持ってるARMはhpcarmくらいなんだが、こいつは

  • __ARM_ARCH_4__(StrongARM SA-1100/1110)
  • __ARM_ARCH_5__(XScale PXA270)

で最低でもARMv4のはずなんだが、クロスのgccは

$ echo __ARM_ARCH_3__ | /usr/tooldir/bin/arm--netbsdelf-gcc -E -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
1

とOpenSSLのARM用のアセンブラコードがサポートしとらん__ARM_ARCH_3__を自称するしもうわからん。

さらにはarch/arm/crypto.incみると

.PATH.S: ${.PARSEDIR}
CPUID_SRCS = armv4cpuid.S armcap.c armv4-mont.S armv4-gf2m.S
CPUID = yes
CPPFLAGS += -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m
.if !empty(MACHINE_ARCH:Mearmv4*) || ${MACHINE_ARCH} == "armeb"
CPPFLAGS += -D__ARM_MAX_ARCH__=4
.elif ${MACHINE_ARCH} == "earmeb" || ${MACHINE_ARCH} == "earmhfeb"
CPPFLAGS += -D__ARM_MAX_ARCH__=5
.elif !empty(MACHINE_ARCH:Mearmv6*eb)
CPPFLAGS += -D__ARM_MAX_ARCH__=6
.else
CPPFLAGS += -D__ARM_MAX_ARCH__=8
.endif
.include "../../crypto.inc"

となってて強制的に__ARM_MAX_ARCH__を指定しててカオスもいいところなのだ。

*1:正確には4-clause BSDL(SSLeay License)とAPL1.0のデュアルライセンスね

2019/07/22(Mon)

[近況] RFIDゲートが欲しい

我が家の認知症老人、ここしばらくは物盗られ妄想からカプグラ症候群にステップアップしたようで、家族は全員別人にすりかわり自分はどこか知らない家に拉致監禁されてるというロールプレイをはじめた。 なもんで隙あらば窓から叫んだり外飛び出して通行人に助けを求めたり深夜徘徊して自分の家と思い込んだ隣家に押入ろうとしたりするので、四六時中気の休まる時間が無いですわ。

こうなるともう中華監視カメラとかの類は力不足で、非接触のICタグかなんかで火元や出入口にアンテナ置いて夜間に近づいたら即アラートとかでもないと無理なんだろうけど、工作で何とかなるレベルじゃなさそうよね。

2019/07/23(Tue)

[SCM] git-subtreeの落とし穴

以前はcontribだったけど現在は本体に取り込まれたgit-subtree、こいつは3rd partyなソースの管理に便利なんだけどrebaseが絡むとややこしいのよな。毎回忘れるのでメモ残しておく。

まずgit subtree addした後、それより以前のcommitに間違いを発見してrebaseを実行するようなケース、簡単な図にすると

	A (master) edit master 1
	|
	B (master) subtree add onto master
	|
	C (master) edit master 2

という履歴があった場合、Aを改変すべく

$ git rebase -i A

を実行すると、なぜかBの時点で実行した

$ git subtree add --prefix=foo --squash remote master

の--prefixが最適用の際に無視されてしまい、ディレクトリ構成が変になるわAのソースが上書きされCの差分適用でconflictが発生するので、お前は全身の穴から血を吹いて死ぬ。

例えばワイのオレオレN6ではOpenSSLをsubtree化してるのだけど、subtree add以前のcommitからrebaseを実行するとこうなる。

$ git checkout tnozaki-openssl
$ git rebase a25e71bd8d516744e119cf08eaf89ed9c3a11ec2
CONFLICT (add/add): Merge conflict in tools/Makefile
Auto-merging tools/Makefile
CONFLICT (add/add): Merge conflict in .gitignore
Auto-merging .gitignore
error: could not apply 44cfd356c... Squashed 'crypto/external/bsd/openssl/dist/' content from commit 76599d516c
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 44cfd356c... Squashed 'crypto/external/bsd/openssl/dist/' content from commit 76599d516c

前述の通りsubtree addで指定した--prefix=src/crypto/external/bsd/openssl/distが無視されてしまい

と本来はprefix以下に置かれるべきファイルがrepository rootに存在するファイルを上書きしてしまい、conflictが発生してしまうのだ。

わざわざ実装読みたくねえし原因調べる気もないのでこれが正解かは知らんけど、git rebaseに-r/--rebase-mergesオプションをつけて実行してmerge commit情報を残すといいみたい。

$ git rebase --rebase-merges a25e71bd8d516744e119cf08eaf89ed9c3a11ec2
Rebasing (2/59)
Checking out files: 100% (2278/2278), done.
Rebasing (5/59)
Checking out files: 100% (2199/2199), done.
Checking out files: 100% (2278/2278), done.
Checking out files: 100% (569/569), done.
Checking out files: 100% (24/24), done.
Successfully rebased and updated refs/heads/tnozaki-openssl.

はい--prefixが維持されてsubtree addが適用されるので正常にrebaseできまんた。

そんでお次、今度は

というケース、これも言葉じゃ伝わりにくいので図にすると

	A (master) edit master 1
	|\
	| B (branch) edit branch 1
	| |
	| C (branch) subtree add onto branch
	| |
	| D (branch) edit branch 2
	|
	E (master) edit master 2

という状態から

$ git rebase master

を実行して

	A (master) edit master 1
	|
	E (master) edit master 2
	 \
	  B (branch) edit branch 1
	  |
	  C (branch) subtree add onto branch
	  |
	  D (branch) edit branch 2

としたい場合やね、でもこれもまたエラーになってしまう。

さっきと同様にオレオレN6でやってみた場合の失敗ログはこちら。

$ git rebase master
First, rewinding head to replay your work on top of it...
Generating patches: 100% (54/54), done.
Applying: ENHANCEMENT: temporary remove crypto/external/bsd/openssl/dist for git subtree.
Applying: Squashed 'crypto/external/bsd/openssl/dist/' content from commit 76599d516c
Using index info to reconstruct a base tree...
.git/rebase-apply/patch:1285: trailing whitespace.
     the certificate can be used for (if anything). Set valid_flags field
.git/rebase-apply/patch:1328: trailing whitespace.
  *) Initial experimental support for explicitly trusted non-root CAs.
.git/rebase-apply/patch:1379: trailing whitespace.
  *) New ctrls to retrieve supported signature algorithms and
.git/rebase-apply/patch:1584: trailing whitespace.

.git/rebase-apply/patch:1754: trailing whitespace.
  *) Fix for TLS record tampering bug. A carefully crafted invalid
warning: squelched 7650 whitespace errors
warning: 7655 lines add whitespace errors.
Falling back to patching base and 3-way merge...
CONFLICT (add/add): Merge conflict in tools/Makefile
Auto-merging tools/Makefile
CONFLICT (add/add): Merge conflict in .gitignore
Auto-merging .gitignore
error: Failed to merge in the changes.
Patch failed at 0002 Squashed 'crypto/external/bsd/openssl/dist/' content from commit 76599d516c
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

やっぱり.gitignoreとtools/Makefileのconflictなので、subtree addの--prefixが失われたことが原因と思われる。

これもやっぱり-r/--rebase-mergesオプションをつければおk。

$ git rebase --rebase-merges master
Checking out files: 100% (2278/2278), done.
Checking out files: 100% (2199/2199), done.
Checking out files: 100% (2278/2278), done.
Checking out files: 100% (569/569), done.
Checking out files: 100% (3/3), done.
Checking out files: 100% (11/11), done.
Successfully rebased and updated refs/heads/tnozaki-openssl.

しかしBitbucketの運営元である暮らし安心 Altassianのブログには

あなたは sub-tree の含まれるリポジトリをどうやってリベースしていますか? この Stack Overflow に関する議論から分かることは、銀の弾丸は存在しないということです。

有効な手順は、手動でリベースを行うために単純に rebase --interactive を実行し、git subtree add のコミットを削除して rebase --continue を実行し、リベースが完了したら git subtree add コマンドを再実行することだと思います。

などと書いてある、Stackoverflowがソースってのがアレやけどまぁワイより何十倍もgitに詳しいだろうから、--rebase-mergesではダメなケースもあるのかもしれない。 つーか古いバージョンの話をしているのだろうか…

そして最後にgit subtree addする際には必ず--squashを忘れないこと、でないとrebaseをする時に

という落とし穴があるのだ。

結論、やっぱりgit捨てたい。

2019/07/24(Wed)

[オレオレN6] OpenSSL + ARM arch

前回の続き、オレオレN6のOpenSSLがhpcarmでビルド止まるのはクロス用のgccが__ARM_ARCH_3__なのでarm_arch.hの中で未サポートのCPUと判定されるからなんだが、N8で問題が起きないのは__ARM_ARCH_5TEJ__を返すからちゅーことか。

$ echo __ARM_ARCH_5TEJ__ | /usr/tooldir/bin/arm--netbsdelf-eabi-gcc -E -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
1

ということで、今のMakefile中では

.if !empty(MACHINE_ARCH:Mearmv4*) || ${MACHINE_ARCH} == "armeb"
CPPFLAGS += -D__ARM_MAX_ARCH__=4
.elif ${MACHINE_ARCH} == "earmeb" || ${MACHINE_ARCH} == "earmhfeb"
CPPFLAGS += -D__ARM_MAX_ARCH__=5
.elif !empty(MACHINE_ARCH:Mearmv6*eb)
CPPFLAGS += -D__ARM_MAX_ARCH__=6
.else
CPPFLAGS += -D__ARM_MAX_ARCH__=8
.endif

としてMACHINE_ARCHで条件分岐してOpenSSLローカルの定義である__ARM_MAX_ARCH__をセットしとるんだけどこれは間違いであり

diff --git a/crypto/external/bsd/openssl/lib/libcrypto/arch/arm/crypto.inc b/crypto/external/bsd/openssl/lib/libcrypto/arch/arm/crypto.inc
index e11de9e953..699ee2de0e 100644
--- a/crypto/external/bsd/openssl/lib/libcrypto/arch/arm/crypto.inc
+++ b/crypto/external/bsd/openssl/lib/libcrypto/arch/arm/crypto.inc
@@ -3,13 +3,13 @@ CPUID_SRCS = armv4cpuid.S armcap.c armv4-mont.S armv4-gf2m.S
 CPUID = yes
 CPPFLAGS += -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m
 .if !empty(MACHINE_ARCH:Mearmv4*) || ${MACHINE_ARCH} == "armeb"
-CPPFLAGS += -D__ARM_MAX_ARCH__=4
+CPPFLAGS += -D__ARM_ARCH__=4
 .elif ${MACHINE_ARCH} == "earmeb" || ${MACHINE_ARCH} == "earmhfeb"
-CPPFLAGS += -D__ARM_MAX_ARCH__=5
+CPPFLAGS += -D__ARM_ARCH__=5
 .elif !empty(MACHINE_ARCH:Mearmv6*eb)
-CPPFLAGS += -D__ARM_MAX_ARCH__=6
+CPPFLAGS += -D__ARM_ARCH__=6
 .else
-CPPFLAGS += -D__ARM_MAX_ARCH__=8
+CPPFLAGS += -D__ARM_ARCH__=8
 .endif
 .include "../../crypto.inc"

として本来はコンパイラが正しい値をセットするはずの(現状はしていない)__ARM_ARCH__を指定して、arm_arch.hの条件分岐を機能するようにしろってことかね。

あとワイはevb*とか基板剥きだしのオタクプロダクツには近寄らん主義なのでさっぱり判らんのだけど、/etc/mk.confに

USR_OBJMACHINE=yes
OBJMACHINE=yes

を設定しただけではMACHINE_ARCHが異なる場合もobjdirが同じで困るんだが、これ明示的に別のディレクトリにするにはわざわざbuild.shの引数で設定しないとダメなんすかね、めんどい。

[オレオレN6] OpenSSLアップデート作業もうそろそろ片付きそう

ようやくopensslconf.hのMD化を終えてN6でサポートされてるCPUはひととおりビルド通るのを確認、x86_64とsparc64は32/64bitでかっこわるいifdef入れてるけど、それぞれi386とsparcのopensslconf.hもインストールするようにして

#if defined(__x86_64__)
#include <openssl/x86_64/opensslconf.h>
#elif defined(__i386__)
#include <openssl/i386/opensslconf.h>
#endif

みたいなwrapperを用意した方がよさそうだけど、それは後回し。

そんでOpenSSLのコードには最適化のための黒魔術

# DES_PTR       use pointer lookup vs arrays in the DES in crypto/des/des_locl.h
# DES_RISC1     use different DES_ENCRYPT macro that helps reduce register
#               dependancies but needs to more registers, good for RISC CPU's
# DES_RISC2     A different RISC variant.
# DES_UNROLL    unroll the inner DES loop, sometimes helps, somtimes hinders.
# BN_LLONG      use the type 'long long' in crypto/bn/bn.h
# RC4_INDEX     define RC4_INDEX in crypto/rc4/rc4_locl.h.  This turns on
#               array lookups instead of pointer use.
# RC4_CHUNK     enables code that handles data aligned at long (natural CPU
#               word) boundary.
# BF_PTR        use 'pointer arithmatic' for Blowfish (unsafe on Alpha).
# BF_PTR2       intel specific version (generic version is more efficient).

というマクロが大量にあって、Configureを実行するとターゲットのCPUに合わせた設定をopensslconf.hに定義してくれるんだが

で定義される値がバラバラで、どれがちゃんとベンチ回して測定して決めた最適値なのか判らんのよな。 特に今opensslconf.hにではなくCPPFLAGSで渡してる値なんてそれこそSSLeay時代からの設定をそのまま秘伝のタレ状態で引継いでて、廃止されてるはずの指定あったりで信用性がちょっとね…

今はpkgsrcのパッチの値を採用してopensslconf.hを生成して放り込んだけど、それでもOpenBSD(LibreSSL)やLinuxの設定値と結構違いがあるのだ(CPU同じなら一緒やろ)、ちゃんとマシン用意してベンチ回して検証せんと駄目だわな。 とはいえしまいこんでる産廃ども(SUN Blade150, Mac Mini G4, Jornada 710, W-ZERO3複数)を引っ張り出して火入れてられるような家庭の状態じゃねえからな…

しゃーないのでgxemulとかQEMUでお茶濁すか、どうせ今更エミュ以外で動かす奴もおらんだろうし…

ということでmasterへのmergeのblockerになっとるlint(1)のfalse alarm問題以外はだいたい片付いたから、そっちの退治に戻りますかね…ああ読みたくねえ…

2019/07/25(Thu)

[オレオレN6] debugging lint(1) その4

前回はlex(1)による字句解析側を調べた結果

という事までは調べたので、今度はyacc(1)側の調査。

yacc(1)のソースは%%と%%で囲まれた中に、BNF記法によく似た書式で構文規則を記述していく。

%%
program:
          /* empty */ {
          	...
          }
        | translation_unit
        ;

translation_unit:
          ext_decl
        | translation_unit ext_decl
        ;
...
%%

ここでジェイコム1円61万株…?みずぽ大量誤発注…?という人は「バッカス・ナウア記法」でお勉強のお時間なんやな。 ナウアつっても日高義樹のワシントンリポートも無関係なのである。 ふつーのプログラマならすでにマスター済やろうからBNFを読むようにこのyaccの構文規則を読み進めていけばいいだけ…

…なんだがプログラミング言語Cの構文規則はそれなりに複雑なので、時間がかかり過ぎるのであまり現実的ではないやね。

かといって一般的なCのデバッガ(gdbなど)で障害部位の特定をしようにも、自動生成された有限オートマトン(日本に帰化したサッカー選手の名前っぽい)による大量の謎テーブルとスイッチ文のラベルでまず心が折れるのだ。

ということでprintfデバッグの時間だね(ニッコリ)、つーかいちいちprintfを入れずともyaccにはYYDEBUGというデバッグ支援機能があってトレースログを出力することが可能、こいつを有効にするには

という手順が必要になる、さいわいlint(1)のMakefileには

diff --git a/usr.bin/xlint/lint1/Makefile b/usr.bin/xlint/lint1/Makefile
index b02b7ffdf8..e28721ab78 100644
--- a/usr.bin/xlint/lint1/Makefile
+++ b/usr.bin/xlint/lint1/Makefile
@@ -7,9 +7,9 @@ SRCS=           cgram.y scan.l mem1.c mem.c err.c main1.c decl.c tree.c func.c \
                init.c emit.c emit1.c inittyp.c tyname.c print.c
 MAN=           lint.7
 YHEADER=
-#DBG=-g
-#CPPFLAGS+=-DYYDEBUG=1
-#YFLAGS+=-v
+DBG=-g
+CPPFLAGS+=-DYYDEBUG=1
+YFLAGS+=-v

 CPPFLAGS+=     -I${.CURDIR} -I. -DPASS=\"${PROG}.h\"

とすでに定義がされてるので、コメント外して有効にすればいい。

それでは前回作った問題のおきないコード

typedef void *foo;
void bar(void (*bar)(void))
{
}

と問題が発生する最小ケース

typedef void *foo;
void bar(void (*foo)(void))
{
}

をそれぞれYYDEBUGを有効にしたlint(1)に喰わせてその出力の差分をみてみよう。

--- OK.txt      2019-07-25 12:46:57.000000000 +0900
+++ NG.txt      2019-07-25 12:47:13.000000000 +0900
@@ -83,23 +83,29 @@
 yydebug: state 419, shifting to state 65
 yydebug: state 65, reducing by rule 171 (asterisk : T_MULT)
 yydebug: after reduction, shifting from state 419 to state 70
-yydebug: state 70, reading 316 (T_NAME)
+yydebug: state 70, reading 317 (T_TYPENAME)
 yydebug: state 70, reducing by rule 167 (pointer : asterisk)
 yydebug: after reduction, shifting from state 419 to state 413
-yydebug: state 413, shifting to state 412
-yydebug: state 412, reducing by rule 162 (direct_notype_param_decl : T_NAME)
-yydebug: after reduction, shifting from state 413 to state 488
-yydebug: state 488, reading 262 (T_RPARN)
-yydebug: state 488, reducing by rule 161 (notype_param_decl : pointer direct_notype_param_decl)
-yydebug: after reduction, shifting from state 419 to state 496
-yydebug: state 496, shifting to state 541
-yydebug: state 541, reducing by rule 156 (direct_param_decl : T_LPARN notype_param_decl T_RPARN)
-yydebug: after reduction, shifting from state 308 to state 423
-yydebug: state 423, reading 261 (T_LPARN)
-yydebug: state 423, shifting to state 106
+unko.c(2): syntax error 'foo' [249]
+yydebug: error recovery discarding state 413
+yydebug: error recovery discarding state 419
+yydebug: error recovery discarding state 308
+yydebug: error recovery discarding state 184
+yydebug: state 111, error recovery shifting to state 177
+yydebug: state 177, error recovery discards token 317 (T_TYPENAME)
+yydebug: state 177, reading 262 (T_RPARN)
+yydebug: state 177, shifting to state 304
+yydebug: state 304, reducing by rule 183 (abs_decl_param_list : abs_decl_lparn error T_RPARN)
+yydebug: after reduction, shifting from state 85 to state 109
+yydebug: state 109, reducing by rule 176 (param_list : abs_decl_param_list)
+yydebug: after reduction, shifting from state 85 to state 129
+yydebug: state 129, reducing by rule 151 (type_direct_decl : type_direct_decl param_list)
+yydebug: after reduction, shifting from state 46 to state 85
+yydebug: state 85, reading 261 (T_LPARN)
+yydebug: state 85, shifting to state 106
 yydebug: state 106, reading 289 (T_TYPE)
 yydebug: state 106, reducing by rule 184 (abs_decl_lparn : T_LPARN)
-yydebug: after reduction, shifting from state 423 to state 111
+yydebug: after reduction, shifting from state 85 to state 111
 yydebug: state 111, reducing by rule 46 (clrtyp :)
 yydebug: after reduction, shifting from state 111 to state 51
 yydebug: state 51, shifting to state 25
@@ -120,56 +126,30 @@
 yydebug: after reduction, shifting from state 111 to state 180
 yydebug: state 180, shifting to state 305
 yydebug: state 305, reducing by rule 182 (abs_decl_param_list : abs_decl_lparn vararg_parameter_type_list T_RPARN)
-yydebug: after reduction, shifting from state 423 to state 109
-yydebug: state 109, reducing by rule 176 (param_list : abs_decl_param_list)
-yydebug: after reduction, shifting from state 423 to state 499
-yydebug: state 499, reducing by rule 159 (direct_param_decl : direct_param_decl param_list)
-yydebug: after reduction, shifting from state 308 to state 423
-yydebug: state 423, reading 262 (T_RPARN)
-yydebug: state 423, reducing by rule 153 (param_decl : direct_param_decl)
-yydebug: after reduction, shifting from state 308 to state 422
-yydebug: state 422, reducing by rule 193 (parameter_declaration : declspecs deftyp param_decl)
-yydebug: after reduction, shifting from state 111 to state 182
-yydebug: state 182, reducing by rule 188 (parameter_type_list : parameter_declaration)
-yydebug: after reduction, shifting from state 111 to state 181
-yydebug: state 181, reducing by rule 185 (vararg_parameter_type_list : parameter_type_list)
-yydebug: after reduction, shifting from state 111 to state 180
-yydebug: state 180, shifting to state 305
-yydebug: state 305, reducing by rule 182 (abs_decl_param_list : abs_decl_lparn vararg_parameter_type_list T_RPARN)
 yydebug: after reduction, shifting from state 85 to state 109
 yydebug: state 109, reducing by rule 176 (param_list : abs_decl_param_list)
 yydebug: after reduction, shifting from state 85 to state 129
 yydebug: state 129, reducing by rule 151 (type_direct_decl : type_direct_decl param_list)
 yydebug: after reduction, shifting from state 46 to state 85
-yydebug: state 85, reading 257 (T_LBRACE)
+yydebug: state 85, reading 262 (T_RPARN)
 yydebug: state 85, reducing by rule 145 (type_decl : type_direct_decl)
 yydebug: after reduction, shifting from state 46 to state 83
-yydebug: state 83, reducing by rule 21 (func_decl : declspecs deftyp type_decl)
-yydebug: after reduction, shifting from state 8 to state 6
-yydebug: state 6, reducing by rule 16 ($$1 :)
-yydebug: after reduction, shifting from state 6 to state 22
-yydebug: state 22, reducing by rule 22 (opt_arg_declaration_list :)
-yydebug: after reduction, shifting from state 22 to state 54
-yydebug: state 54, reducing by rule 17 ($$2 :)
-yydebug: after reduction, shifting from state 54 to state 95
-yydebug: state 95, shifting to state 140
-yydebug: state 140, reducing by rule 251 (comp_stmnt_lbrace : T_LBRACE)
-yydebug: after reduction, shifting from state 95 to state 142
-yydebug: state 142, reading 258 (T_RBRACE)
-yydebug: state 142, shifting to state 210
-yydebug: state 210, reducing by rule 252 (comp_stmnt_rbrace : T_RBRACE)
-yydebug: after reduction, shifting from state 142 to state 240
-yydebug: state 240, reducing by rule 247 (comp_stmnt : comp_stmnt_lbrace comp_stmnt_rbrace)
-yydebug: after reduction, shifting from state 95 to state 141
-yydebug: state 141, reducing by rule 18 (func_def : func_decl $$1 opt_arg_declaration_list $$2 comp_stmnt)
-unko.c(2): warning: argument bar unused in function bar [231]
-yydebug: after reduction, shifting from state 8 to state 11
-yydebug: state 11, reducing by rule 6 (ext_decl : func_def)
+unko.c(2): syntax error ')' [249]
+yydebug: error recovery discarding state 83
+yydebug: error recovery discarding state 46
+yydebug: error recovery discarding state 15
+yydebug: state 8, error recovery shifting to state 1
+yydebug: state 1, error recovery discards token 262 (T_RPARN)
+yydebug: state 1, reading 257 (T_LBRACE)
+yydebug: state 1, error recovery discards token 257 (T_LBRACE)
+yydebug: state 1, reading 258 (T_RBRACE)
+yydebug: state 1, shifting to state 16
+yydebug: state 16, reducing by rule 15 (data_def : error T_RBRACE)
+yydebug: after reduction, shifting from state 8 to state 12
+yydebug: state 12, reducing by rule 7 (ext_decl : data_def)
 yydebug: after reduction, shifting from state 8 to state 23
 yydebug: state 23, reducing by rule 4 (translation_unit : translation_unit ext_decl)
 yydebug: after reduction, shifting from state 0 to state 8
 yydebug: state 8, reading 0 (end-of-file)
 yydebug: state 8, reducing by rule 2 (program : translation_unit)
 yydebug: after reduction, shifting from state 0 to state 5
-Lint pass2:
-bar defined( unko.c(2) ), but never used

この出力をパッと見て気づくのは

-yydebug: state 70, reading 316 (T_NAME)
+yydebug: state 70, reading 317 (T_TYPENAME)

がトリガーとなって後の構文解析エラーが起きてるってことで、これは その3で字句解析側のコード監査で登場したname関数

406 static int
407 name(void)
408 {
409         char    *s;
410         sbuf_t  *sb;
411         sym_t   *sym;
412         int     tok;
413
414         sb = allocsb();
415         sb->sb_name = yytext;
416         sb->sb_len = yyleng;
417         sb->sb_hash = hash(yytext);
418         if ((sym = search(sb)) != NULL && sym->s_keyw) {
419                 freesb(sb);
420                 return (keyw(sym));
421         }
422
423         sb->sb_sym = sym;
424
425         if (sym != NULL) {
426                 if (blklev < sym->s_blklev)
427                         LERROR("name()");
428                 sb->sb_name = sym->s_name;
429                 sb->sb_len = strlen(sym->s_name);
430                 tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
431         } else {
432                 s = getblk(yyleng + 1);
433                 (void)memcpy(s, yytext, yyleng + 1);
434                 sb->sb_name = s;
435                 sb->sb_len = yyleng;
436                 tok = T_NAME;
437         }
438
439         yylval.y_sb = sb;
440         return (tok);
441 }

の中で

って処理が問題なのだという事が証明されたやね、そもそも関数の引数名にまでシンボルテーブルを検索してtypedefと置換する必要なんて無いわけでな。

ということでトークンが変数名ならこのシンボルテーブルの検索をスキップすりゃよさそうなんだが、このトークンは変数名って情報がどこにも無さそうでなぁ…

あと完全にスキップしてしまうとシンボルテーブルにtypedefだけでなくグローバル変数なんかもあったりすると、グローバル変数名をローカル変数名が隠してしまういわゆるシャドウパラメータの検知ができなくなったりしないかなぁという心配があるのでそこの検証もだな。

@次回

つーことでsym_tとsymtabの実装をもうちょい読み進めましょうかね…ハァ…

2019/07/26(Fri)

[オレオレN6] debugging lint(1) その5

ふーむ、どうもN8のlint(1)のソースの変更履歴ながめとったら このコミットで問題のopensslとzlibのconflictする定義を切り出したテストコードが放り込まれてるのに気づいた、そんで このコミットでこのfalse alarm問題は修正したぜということらしい。

後者のコミットの差分をN6でビルド通るように%expectの値 *1を修正したものがこちら。

diff --git a/usr.bin/xlint/lint1/cgram.y b/usr.bin/xlint/lint1/cgram.y
index 646e0a21bd..74f149e213 100644
--- a/usr.bin/xlint/lint1/cgram.y
+++ b/usr.bin/xlint/lint1/cgram.y
@@ -107,7 +107,7 @@ static inline void RESTORE(const char *file, size_t line)
 #endif
 %}

-%expect 5
+%expect 8

 %union {
        int     y_int;
@@ -982,7 +982,7 @@ notype_param_decl:
        ;

 direct_notype_param_decl:
-         T_NAME {
+         identifier {
                $$ = dname(getsym($1));
          }
        | T_LPARN notype_param_decl T_RPARN {

引数名について字句解析がT_NAMEを返してきた場合だけ構文解析にマッチするようにしてたのを

identifier:
          T_NAME {
                $$ = $1;
          }
        | T_TYPENAME {
                $$ = $1;
          }
        ;

と、T_NAMEだけでなくT_TYPENAMEどちらでもマッチするようにしたってこと。

とりあえずこの変更を取り込めば現在発生するfalse alarmは出なくなるのだけど、本質的にこのパッチは対症療法でしかないよね… *2

というのも本来はtypedefの影響を受けないはずの変数名がname()関数内で無理矢理痴漢されてT_TYPENAMEとして扱われてるって根本的なところが直ってないのだ。 例えば以下のコード

typedef int foo;
int bar(int foo)
{
}

に対してlint(1)を実行すると

$ lint -z /home/tnozaki/unko.c
unko.c:
unko.c(2): warning: argument foo unused in function bar [231]
Lint pass2:
bar defined( unko.c(2) ), but never used

とシンタックスエラーは出ないけど、YYDEBUGを有効にしてトレースを確認すると

yydebug: state 0, reading 288 (T_SCLASS) ← typedef
...
yydebug: state 14, reading 289 (T_TYPE) ← int
...
yydebug: state 15, reading 316 (T_NAME) ← foo
...
yydebug: state 8, reading 289 (T_TYPE) ← int
...
yydebug: state 15, reading 316 (T_NAME) ← bar
...
yydebug: state 106, reading 289 (T_TYPE) ← int
...
yydebug: state 184, reading 317 (T_TYPENAME) ← foo
...

という具合で、barの引数名であるfooがT_NAMEではなくT_TYPENAMEに化けてることがわかる。 まぁ化けてても現状では文法チェックに影響を与えてはいないのだが潜在バグだからねこれ…

ただtypedefへの置換をname()関数で行う限り、現在処理しているトークンが予約語なのか型名なのかシンボル名なのか変数名なのかはわからない。 どうあがいても構文解析側でしかわからんものを字句解析側でやろうとすること自体が頭おかしいコードなので、このへんでお茶濁すのもまぁ手かもしれない。

正しい修正についてはまた次回を待て、いや次回で直ってる気がしないんだが…

*1:シフト還元衝突の警告を抑制する魔法、yacc実行した時に「n shift/reduce conflicts」といわれた数字を入れとけばだいたいおk
*2:まぁcommitした人の名前をみればまたお前か案件なので以下略

2019/07/27(Sat)

Tycho/Fuji Rock 2019

さすがにTychoがTwitterトレンドとiTunes Storeのトップになっとるのは目を疑ったけど、初の日本単独公演の頃から妙に客層幅広いのが印象に残るバンドだったので、耳に届きさえすればの実力ですわね、いいぞもっと売れて老害ロックを駆逐しよう。

配信があったのありがたい、音小さいしエンコ重くてプチプチ切れるとか不満はあったけどね。

セトリは新作と前作が多め、やっぱフジロック(笑)だから時間短くて曲数がこれから盛り上がるのに~ってとこですな。

  1. A Walk (from "Dive")
  2. L (from "Awake")
  3. Weather (from "Weather")
  4. (M.C.)
  5. Japan (from "Weather")
  6. Easy (from "Weather")
  7. For How Long (from "Weather")
  8. Pink & Blue (from "Weaher")
  9. Awake (from "Awake")
  10. (M.C.)
  11. Horizon (from "Epoch")
  12. Epoch (from "Epoch")
  13. Division (from "Epoch")
  14. (M.C.)
  15. No Stress (from "Weather")

なのでBEATNIKがアルバム発売にあわせて単独公演ブックせずにこのままフジロックだけでお茶濁そうって気なら、これまでのPLANCHAに権利返してやってくれ感あるよな、あそこは普通の神経ならとばす名古屋入れるくらい本気だった。 なおPLANCHAは今日はいちファンとして客席でキャッキャしてオタク特有の早口のツイートしておった、さすがやな。

あと前ステージがTycho好きならToro y Moiも好きでしょといういかにもフジロック(笑)の音楽聴かずに文字情報だけでブックしてる感ほんときらい、なぜいっとき同じチルウェイブというジャンル扱いされたのか、ほんと理解に苦しむんだけどあれ…

2019/07/28(Sun)

[オレオレN6] まだOpenSSLいじってる

ローカルパッチの監査は終ったしlint(1)バグの緩和策もあったのでいよいよマージかけようかと思ったんだけど、Makefileから渡してるCPPFLAGSなんかもすげー怪しいのでこっちも監査せんとダメだわ。

つーかlibcrypto/(arch/*/)?*.incによるビルドシステムは破綻しとるのよね、元はというと

というコンセプトではじまったっぽいけど、そのperl scriptとやらがアレだったのかCVSから消され、その後はOpenSSLのバージョンアップの度に手作業で変更してるという賽の河原なのである、そもそも元のOpenSSLのビルドシステム自体が無茶苦茶だしそれに追従しようとしたら破綻するよなそら。

本当はOpenBSDみたいなMakefile wrapperで極力手間減らすビルドシステムがいいんだろうけど、Nはクロスビルド必須の上にベースシステムにperlが無いからまぁ難しい。

おかげで普通にtarball展開してビルドする時に定義されるCPPFLAGSがx86_64だけでもこれだけ漏れてるようでアレ。

ざっと見た限りでは

という感じ、こいつらも対応せんと性能的にpkgsrc使った方が高速みたいな本末転倒なことになってそうやな…

あとPA-RISCとMIPSでも高速化のためのアセンブラコードを吐くperl scriptがあるんだがNでは使われてない、ただまぁ

実機も無エ
需要も無エ
まったぐユーザー俺一人
エミュレーターあるけれど
動かし方を読む気が無エ
婆さんと爺さんはボケて毎日ぐーるぐる

なので対応する気はないです。

2019/07/29(Mon)

[オレオレN6] まだまだOpenSSLいじってる

とりあえずECP_NISTZ256は1.0.2kではコードは存在するけどデフォルトではビルドされてないのでいいのか、つーかx86_64以外はそもビルドできないっぽ。

あと過去記事にもあるとおりSHA256/512実装がOpenSSLのものでなくlibcにあるものが使われるように改造されとるんだが、そのせいでe_aes_cbc_hmac_sha256.cが-DAES_ASMすると無条件で-DSHA256_ASM前提になるのでビルドエラーになる。 これはOpenSSL側のifdefが悪いので対応をブチ込んでおく。

diff --git a/crypto/external/bsd/openssl/dist/crypto/evp/e_aes_cbc_hmac_sha256.c b/crypto/external/bsd/openssl/dist/crypto/evp/e_aes_cbc_hmac_sha256.c
index 46c9d03389..3548c63a10 100644
--- a/crypto/external/bsd/openssl/dist/crypto/evp/e_aes_cbc_hmac_sha256.c
+++ b/crypto/external/bsd/openssl/dist/crypto/evp/e_aes_cbc_hmac_sha256.c
@@ -90,7 +90,7 @@ typedef struct {

 # define NO_PAYLOAD_LENGTH       ((size_t)-1)

-# if     defined(AES_ASM) &&     ( \
+# if     defined(AES_ASM) && defined(SHA256_ASM) &&     ( \
         defined(__x86_64)       || defined(__x86_64__)  || \
         defined(_M_AMD64)       || defined(_M_X64)      || \
         defined(__INTEL__)      )

あとi386 portでアセンブラコードが軒並み無効になってるのはこれOpenSSLのx86 ASMがi586を最低限の動作環境としとるのに対し、Nはi486だからなんですかね。 それにしてはAESだけは586コード有効になっとるけど、AESだけはAESNIの絡みでCPUIDの結果で動作切替わるようになってたりするんだろうかね、よくわからん。

つーかi386を名乗ってるのにもうi386では動かんしi486も実機なぞ残ってないだろうからグッバイでええやろ…ということでユーザー1名のオレオレN6では全部有効にしておいた。 ただopenssl speedの結果を眺めるに性能は微妙かなぁという気がしないでもない。

んで他のCPUのベンチにQEMU環境を作ろうとしたらTERM無関係に矢印キー効かずsysinst途中から進められなくなるのでクソ、もうsysinst使わずにdisklanbel他でインストールする方法を思い出すほどの気力はねえですわ。