ツールチェーン更新履歴

exeGCCとexeClangの相違点

注釈

SOLID-4.0でRISC-V(RV32/RV64)をサポートする際、ツールチェーンをこれまでのGNUベース(exeGCC)からLLVMベース(exeClang)に変更しました。RISC-Vは新規サポートターゲットなのでexeGCC s007は存在しないのですが、ここではAArch64/ARMのexeGCC s007からの、ターゲット非依存の変更点を解説します。

exeGCC s007とexeClang s008の相違点は以下のようになります。

  • GNU(GCC/Binutils)のソフトウェアを廃止。標準Cライブラリ以外をLLVMに変更

    • s007まで

      • C/C++コンパイラはGCC

      • アセンブラやリンカなどのバイナリユーティリティはBinutils

      • コンパイラランタイムライブラリはGCCのlibgcc

      • 標準C++ライブラリはGCCのlibstdc++

      • GNU makeとKMCオリジナルのUNIXツール(mv/cpなど)を同梱

    • s008

      • C/C++コンパイラとアセンブラはLLVMのClang

      • リンカなどのバイナリユーティリティはLLVM Tools

      • コンパイラランタイムライブラリはLLVMのcompiler-rt

      • 標準C++ライブラリはLLVMのlibc++、libc++abi、libunwind

      • (GNU makeやmv/cpなどのUNIXツールは同梱されておりません。 )

  • 言語規格を更新

    • s007まで

      • gnu11/gnu++14

    • s008

      • gnu17/gnu++17

  • fat LTO サポート

    付属ライブラリ全てを -flto=thin -ffat-lto-objects オプション付きで コンパイルしています。これによって生成された *.o(ライブラリアーカイブ *.a 内部に含まれる) は LTO に必要な情報だけではなく機械語も含むため、 ファイルサイズは大きく(fat)なりますが、従来の ELF ファイル と全く同様に扱えるという利点があります。

  • 標準Cライブラリの変更点

    exeGCCから引き続きNetBSDのlibc/libmをベースにしておりますが、 Solid Sands社(弊社のSOLID開発環境とは無関係)の商用コンパイラテストツール SuperTestを使用し、より標準規格との適合性を高めました。

    • ライブラリの仕様変更

      • -fsigned-char の使用を廃止。

      • 数学ライブラリ(math.hcomplex.h)がerrnoを使用しなくなりました。

        これはC99のmath_errhandling == MATH_ERREXCEPT仕様に準拠します。 この仕様の採用により、-fno-math-errno オプション最適化が可能となります。 (errnoは最適化やマルチスレッドとの相性が悪いため、現代的なツールチェーンの数学ライブラリでは使用されないのが一般的です。)

    以下は詳細となります。

    • math.h

      • サブノーマル領域のケアのためFreeBSDの logb(f)() パッチを適用。

      • 精度の改善のため cbrt(f)()scalbn(f)()fmax(f/l)()fmin(f/l)() に musl libcの実装を使用。

      • fmax(f/l)()fmin(f/l)() の入力にNaNが来た時の挙動が仕様通りになりました。

      • C99のmath_errhandlingサポート。

        • 値は常にMATH_ERREXCEPTのみになります。

        • 例外が仕様通りに発生しない以下の数学関数を修正。

          cosh(f)()exp(f)()lgamma*(f)()expm1(f)()log1p(f))()acosh(f)()atanh(f)()nextafter(f)()

    • C11の uchar.h サポート(musl libcの実装を使用)

      • uchar.h の関数を使用する場合は setlocale() による設定が必要です。

      • setlocale(LC_CTYPE, "") を実装。返る文字列は "C""UTF-8""cp932" の いずれかとなります。

      • setlocale(LC_CTYPE, locale) のlocaleに "en_US.UTF-8" など、 部分文字列に有効なロケールが含まれている文字列を渡せるようになりました。

        • 有効な部分文字列(大文字小文字を区別しません)は以下になります。

          • "C" or "POSIX" (この2つは完全一致のみ)

          • "NONE"

          • "UTF-8" or "UTF8"

          • "cp932" or "MSKanji"

        ただし、現在サポート(テスト)されているのは"C"と"UTF-8"のみです。

      • それに伴うワイド文字関数の修正。

        • mbtowc(wchar *pwc, const char *s, size_t n)

          nが0の時sを一切参照せずに-1と EILSEQ (errno)を返すように修正。

        • wint_t btowc(int c)

          入力値cをunsigned charにキャストしてから判定していなかったのを修正。

          btowc(x) == btowc((unsigned char)x) が成り立たなければいけませんが、 ASCII/UTF-8でcが256以上の場合不成立になっていました。

          (サポート対象外のcp932(Shift_JIS)は未修正のままです。)

        • mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)

          前回の戻り値が-2でリスタートした際、s==NULLの場合常に psを初期化して成功していたのを修正。リスタート時はs==NULLの 場合-1と EILSEQ (errno)を返すようになりました。

        • strftime()/wcsftime() のC99で追加された仕様を実装。

          %g %G %V の実装にmusl libcのコードを使用。

        • wctrans()"tolower" または "toupper" を渡した時に 仕様通りに動作しないバグを修正。

    • soft float時の fenv.h 関数が、errnoと同様にマルチスレッド対応が可能になりました。source/errno.c 内の変数が増えたので一つの構造体にまとめました。

    • *scanf()%n を実行するたびに戻り値が1増えていたバグを修正。

    • *snprintf() のバッファサイズが足りない場合に %n の結果が正しくないバグを修正。

    • sys/_vlink_syscalls.h の関数プロトタイプに、上位関数に合わせてconst付与。関連するソースコードを修正。

    • stderr/stdoutへの出力時に改行コードLFをCRLFに変換していたのを廃止。

    • 浮動小数点数演算エミュレーションライブラリをSoftFloat-2aから2cにアップデート。 NetBSDが保守している2a版は、既に2cまでの修正パッチの大半が当たっているため、動作は変わりません。このアップデートはRISC-Vの開発過程で発生した問題を調査する際、2a版が既にサイトからダウンロードできなくなっており、今後の保守のために行いました。

ツールチェーン更新履歴 (ARM)

s007

s006 の 64-bit 化とバグ修正アップデート。

  • 実行ファイルが 64-bit(x64)exe になりました。

    • Clang 4.0 と 6.0 はサポート終了。(Clang 12.0 のみ。)

    • solidelf.exe(32 bit)を削除。solidelf64.exe(64 bit)を solidelf.exe にリネーム。

    • libelf を依存関係(gnu/EXEGCC_GNU_SOFTWARE_INFO.txt)から除外。(readme 未記載。)

      libelf の更新が長年止まったままとなっていて、s007 のビルド環境 Ubuntu 20.04 LTS でビルドができなくなりました。そこで exeGCC のビルドシステムから除外したのですが、問題なく s007 がビルドできました。調査の結果 2010-11-03 PR lto/46273 で依存関係から削除されたようで、exeGCC for SOLID の全てのバージョンの GCC で不要だったことがわかりました。

  • LLD サポート(LLVM Linker 17.0.1 追加)。

    • LLD(LLVM Linker)サポートのためリンカスクリプト修正。

  • crt.o_kmc_start1() (ROM-RAM コピー完了前なのでライブラリ関数は使用できない)で最適化により memset() 呼び出しが発生していたのを修正。

  • libc

    • NetBSD 9.1 -> 9.3 ベースにアップデート。

      以下の 2 ファイルにわずかな修正のみ。

      • math.h (コメント修正のみ。)

      • source/stdio/fread.c

    • 日本語コメントの文字コード変換エラーでライブラリがリビルドできない不具合を修正。

    • locale 周りで不正メモリアクセスが発生する不具合を修正。

      locale は "C" 固定という仕様なので、これまで setlocale() などは十分にテストされていませんでした。

    • exit() で libc 内部の mutex を destroy するように修正。 (_libc_destroy() 追加。)

    • Clang で tgmath.h を使用するとコンパイルエラーになるのを修正。

    • complex.h で C11 CMPLX* マクロをサポート。

    • stdio.hfgetpos()/fsetpos()extern "C" 漏れを修正。

    • exit()_Exit() が weak シンボルになっていなかったのを修正。

    • シングルスレッドで _xfer = 0 の場合(デバッグ時、またはシミュレータで実行時)TLS 変数をサポート。

      単純に .tdata のアドレスを tp にセットし、.tbss 領域を 0 クリアするだけの対応です。

      TLS 変数はほとんど使われないと仮定し、本来 .bss と同様に NOLOAD でメモリは確保されない .tbss にメモリ領域を割り当てています。

      .sdata.data セクション内に配置するようにリンカスクリプトを修正。

  • ARM のみ

    • 一部ターゲットで __aeabi_memclr4()/__aeabi_memclr8() がリンクエラーになるのを修正。

    • 内部的な修正

      コンパイラのテスト用 rdimon サポートルーチンが qemu-system-(arm|aarch64) で正しく動作するようになりました。

    • libc_tiny

      bsearch() が全く正しく動作していない不具合を修正。

  • 既知の問題

    もともと C++17 はサポート範囲外ですが、std::aligned_alloc() を使用するとコンパイルエラーが発生します。

    • ARM のみ

      float ABI が hard の時、fma()/fmaf() に NEON の vmla.f64/f32 命令を使用するので、この命令が使用できないターゲットでは動作しません。(s006/s007 同梱 readme 未記載。)

s006

  • ソフトウェアアップデート

    • Clang 6.0.0 -> 12.0.1

    • GCC 6.4.0 -> 10.3.0

      • GMP 6.1.2 -> 6.2.1

      • MPFR 4.0.1 -> 4.1.0

      • MPC 1.1.0 -> 1.2.1

      • libiconv 1.15 -> 1.16

    • binutils 2.28.1 -> 2.36.1

    • GDB 8.1 -> 10.2

      • termcap 1.3.1

      • GNU make 4.2.1

  • GCC 10 と Clang 12 の変更点

    • -fno-common がデフォルトになりました。

      https://gcc.gnu.org/gcc-10/porting_to.html

      これまでと同じ動作にしたい場合は -fcommon を指定してください。

    • Clang 12 のデフォルトの C 言語標準規格は C17 ですが、C17 は C11 の マイナーアップデートであるため、GCC 10 デフォルトの C11 とは 互換性があります。 C++ はどちらも C++14 です。 C も C++ もデフォルトで GNU 拡張が有効です。

      -std=gnu11 or -std=gnu++14

    • GCC 10 で増えた以下のヘッダは Clang では未サポートとなります。

      • arm_bf16.h

      • arm_cde.h

      • arm_cmse.h

      • arm_fp16.h

      • arm_mve.h

      • arm_mve_types.h

  • 新規サポートターゲット

    • Cortex-M3 (ARMv7-M)

    • Cortex-R4(F)/R52(F) (ARMv7-R / VFPv3)

  • libc: NetBSD 7.0 -> NetBSD 9.1.

    NetBSD の libc は枯れているので、既存の部分はほとんど変わっていません。 7.0 では C11 対応が甘かったため、KMC が独自に実装したり、バグやコンパイル エラーを修正していたものの大半が 9.1 では修正されていたので、リベース。

    • 新規サポート関数

      • math.h

        fma(), fmaf()

      • 非標準関数(サポート外)

        • stdio.h

          open_memstream()

          open_wmemstream()

        • stdlib.h

          reallocarr()

          reallocarray()

          strtonum()

        • string.h

          strchrnul()

          strnstr()

          wcsnlen()

    • perror()/strerror()/strerror_r() に不正なエラー番号が渡された場合に不正メモリアクセス が発生するのを修正。

    • asctime()/strftime() に不正な struct tm が渡された場合に不正メモリアクセス が発生するのを修正。また asctime_r() に不正な struct tm が渡された場合、 通常の 26 文字以上のバッファが使用される可能性がある(最大 68 バイト) ので、struct tm の内容をチェックするか、十分に大きなバッファを渡して ください。

    • errno.hperror()/strerror()/strerror_r() の不整合を修正。

    • FAST_SPEED マクロを廃止。

    • libstdc++ の ostringstream に浮動小数点数を渡して文字列に変換しようと すると std::setlocale(LC_NUMERIC, 0) が NULL を返し、NULL 参照が発生して 例外が発生する不具合を修正。同様の問題を防ぐため setlocale() は常に "C" を返すように修正(一切 current locale を変更しません)。

    • osemu.h を非公開に変更。(source/ 以下に移動。)

    • kwin32.h を公開ヘッダに変更。(sys/_vlink_syscalls.h

  • libc_tiny

    • SSP 有効時に gets() のエイリアス __gets() が存在しないためリンクエラーになる 不具合を修正。

    • (v)snprintf(buf, n, ...)buf に NULL、または n0 が渡された場合に 不正メモリアクセスが発生するのを修正。

    • scanf() 系関数の [(^)文字集合] 書式を使用するとスタックオーバーフローが発生する 不具合を修正。

  • libcompiler_rt

    • *vfp 関数が hard/softfp のライブラリ中に存在しない不具合を修正。 (s004、s005 でリグレッション。)

      この関数はライブラリ仕様には存在しますが、おそらく実際には使用されないので 影響は無いと思われます。

  • 非互換性

    • セットアップツールから以下の define を削除。

      __USE_VFP, __MSL_NO_IO_SUPPORT__, __$GCC_CPU$__

s005

  • armcc に似た stdio 等の排他制御スタブを実装しました。

    • libgcc の一部にも使用されます。

    • 詳細は source\mutex_stub.c を参照してください。

  • SOLID の DLL をサポート。

    • 位置独立な libXXX_s.a ライブラリ、specs ファイル、リンカスクリプトを追加。

    • s は shared の意味で、Linux などでは libgcc_s.so のような拡張子になりますが

    • SOLID の DLL では static link なので .a です。

  • SOLID IDE のためのファイルを追加。(platform/

  • libc

    • __aeabi_memset()__aebi_memset() と typo していたバグを修正。

    • localtime()/localtime_r()tm_mdaytm_yday のバグを修正。

    • C11 の aligned_alloc() を追加。

    • GNU sed を追加し、makefile を簡略化。

  • misc

    • man/library_overview_ja.xls.xlsx 形式に変更。

    • bin/gnu_demangle(64).dll を削除。

    • ctime()/gmtime()/localtime()/mktime()/utime() のエラーハンドリングを修正。

    • random_deviceruntime_error を修正(生成するのは疑似乱数なので仕様的には変わらず未サポートとなります。)

    • Clang の内部的な変更。(IDE 内部でのみ使用。)

  • ベアメタル環境対応のための新規ターゲットサポート

    • Cortex-M4/M4F (ARMv7-M / FPv4-SP-D16-M)

    • Cortex-M7/M7F (ARMv7-EM / FPv5-DP-D16-M)

    • Cortex-R5/R7/R8 (ARMv7-R)

  • 省メモリ環境向けのコンパクトな libc、libc_tiny をサポート。

    • 制限

      • C89 までサポート。

      • ASCII のみ。

      • wchar 未サポート。

      • locale は "C" のみ。

      • VLINK(stdio.h)はあくまでもデバッグ用でマルチスレッド未サポート。

      • malloc は簡素な K&R malloc で、メモリが断片化するほどの頻繁 な使用は想定していません。

      • C++ を使えるような環境に向けたものではないので、非推奨。

      • libc と libgcc 以外のライブラリとの互換性は保たれています。(上記サポート仕様外の関数はダミー実装で正常動作しません。)

    • 使用方法

      • コンパイル時に -D_USE_LIBC_TINY を指定。

      • リンク時に -specs=$GCCDIR\lib\$GCC_DEFAULT\tiny.specs を指定。

      • 明示的に指定する場合のライブラリ名は libc_tiny.alibgcc_tiny.a-lc_tiny -lgcc_tiny

s002

  • ソフトウェアアップデート

    • GCC 4.9.4 -> 6.4.0

      • GMP 6.1.2

      • MPFR 3.1.5 -> 4.0.1

      • MPC 1.0.3 -> 1.1.0

      • libiconv 1.14 -> 1.15

    • binutils 2.27 -> 2.28.1

    • GDB 7.12.1 -> 8.1

      • termcap 1.3.1

    • GNU make 4.2.1

    • Clang 4.0.0 -> 6.0.0

  • C は gnu11、 C++ は gnu++14 規格がデフォルトになりました。(GCC 4.x までは gnu89、gnu++98 がデフォルト。)

  • 列挙型が 32 bit 固定になりました。( -fno-short-enums

  • -mfloat-abi=hard をサポートしました。

  • fstat()fd として stdin/stdout/stderr を渡した時にメモリアクセス違反が発生する不具合を修正しました。

    fwrite() など、fstat() を内部で使用する stdio.h のファイル関連関数にも影響があります。)

  • time.h

    • 欠けていた標準関数を実装しました。

    • 未サポートの関数をヘッダからコメントアウトしました。

    • time_t の開始年を DOS Time (1980) から UNIX Time (1970) に変更しました。

    • stat(), fstat(), lstat(), utime() のタイムスタンプ(秒の値)が正しくない不具合を修正しました。(MS-DOS 形式の秒の値は 2 で割った値でした。)

  • stdout が常にバッファリングされてしまい '\n' が来ても fflush() されない不具合を修正しました。

  • stdio が常にリンクされコードサイズが肥大してしまう不具合を修正しました。

    • dlmalloc の malloc_stats()fprintf() を使用するため廃止されました。

    • abort() 内部の fprintf()write() に置き換えました。

    • write() 内部の printf() を削除しました。

    • stdio を使用する ssp ライブラリを libc から分離しました。

  • 不要な関数、データの削除

    • VLINK 有効時

      • ファイルの最大 open 数 (_FD_MAX) を 100 から 20 に削減しました。

      • _LF_flg を廃止しました。ロングファイルネームサポートは常に有効です。

        (変数自体は残っているので既存の crt との互換性は保たれています。)

      • その他(内部実装)

  • arm_neon.h を Clang で使用するとエラーになる問題を修正しました。

  • 整数型のみサポートする *iprintf/*iscanf 関数を追加しました(newlib 拡張)

    詳細は stdio.h を参照してください。

    ただし、これは C99 までの仕様をフルサポートするため、スタック消費量がほとんど変わらず、内部で malloc() も使用するため、省メモリ環境においては SOLID が提供する同名の機能制限版関数の使用を推奨します。(SOLID とは別に、newlib との互換性のために追加された関数。)

s001

最初のリリース。

ツールチェーン更新履歴 (AArch64)

基本的には ARM 版と同じなので、差分のみを記載します。

詳細は readme を参照してください。

s007

  • .data.bss が 4GB を超えるアドレスに配置された場合に VLINK が動作しない不具合を修正。

  • libgcc の一部のアセンブラ実装の関数が .bss の変数を使用するため、.text.bss が 4GB 以上離れるとリンクエラーになる問題を修正。

  • string.h

    ARM optimized routines v23.01 にアップデート。

    https://github.com/ARM-software/optimized-routines/releases/tag/v23.01

    変更点は strcpy() の最適化のみ。

s006

s005

  • ARM s005 とバージョン番号とソースツリーを統一。

    そのため AArch64 の s004 はスキップされ存在しません。

  • libc

    • memmove() のアセンブラコードが large code model 未対応だったのを修正。

  • libc_tiny

    AArch64 は libc_tiny(省メモリ環境向けのコンパクトな libc)をサポートしません。

s003

  • large code model をサポート。

  • Clang の内部的な修正。(生成コードに変化はありません。)

s002

最初のリリース。

ARM 版とバージョン番号を統一したため、AArch64 の s001 は存在しません。

ツールチェーン更新履歴 (RISC-V)

s008

最初のリリース。最初のexeClangリリース。 AArch64/ARMのexeGCCからバージョン番号を引き継ぎました。