2021年06月14日

最近Rustという新しいプログラミング言語が多くの分野で注目を浴びています。RustはC++のような低レベルなコンパイル型言語であり高い効率で動作する一方、強力な型システムやメモリ安全性を保証するための仕組みを備えており、バグの少ないコードを書くことができます。本記事では、TOPPERSカーネルや弊社のSOLID-OS上でRustで書かれたプログラムを動かし、カーネルAPIを使用する方法を紹介します。

続きを読む

2021年04月14日

GCC の場合、ホストの C++ コンパイラのみ(通常は GCC)で、Binutils と GCC のソースコードから完全な C/C++ クロスコンパイラをビルドすることが可能です。

これまで Clang は GCC に依存しており、LLVM プロジェクトのソースコードのみで完全なクロスコンパイラをビルドすることはできない(そのため、GCC のヘッダやライブラリをそのまま使うしかない)という認識でした。この誤解は、CMake が完全な(a.out を生成可能な)C/C++ コンパイラを要求するので、Clang のランタイムライブラリである compiler-rt を Clang 自身でビルドする方法がわからなかったためです。一つでも GCC でライブラリをビルドしてしまうと、そのライブラリは GCC のヘッダに依存することになるので、他のライブラリも全て同じ GCC でビルドしなければなりません。

しかし最近いろいろ調べていて、実はそれが可能であることがわかりました。
ただし、以下の制限があります。(この記事では RISC-V をターゲットとします。他のターゲットでは以下の制限は無い可能性があります。)
  • LLVM のリンカ LLD は RISC-V のデフォルトである -mrelax オプション(Linker optimization/relaxation)のサポートが完全ではないなど、様々な問題があるため、リンカのみ Binutils の GNU ld を使用します。
  • LLVM の C++ ランタイム実装 libc++abi と C++ ライブラリ libc++ が newlib ではビルドできないようなので、今回は C コンパイラのみビルドします。(libc++abi の実装に使用される C++ 例外の実装 libunwind はビルド可能ですが、C の場合は不要なので今回は割愛します。)
  • RISC-V 命令セットシミュレータの spike と一緒に使用する pk カーネルが clang ではビルドできないようなので、spike/pk は今回はビルドせず、以前の環境で GCC を使ってビルドしたものを使用します。(OVPsim の無償版は現在 V 拡張をサポートしていない問題があります。)


続きを読む

2021年02月19日

Binutils や GCC は、Ubuntu 上で Windows で動作する、組み込み向け(RISC-V など)のコンパイラツールチェーンを簡単にビルドできます(カナディアンクロスビルド)。configure の際に --target=riscv64-unknown-elf --host=x86_64-w64-mingw32 --build=x86_64-pc-linux-gnu を指定するだけで、後は基本的にネイティブと同じです。この時、Ubuntu 上(x86_64-pc-linux-gnu)で動作するクロスの x86_64-w64-mingw32-gcc(g++)でビルドが行われるという仕組みです。

Clang の場合、CMake でどのように設定すれば良いのかとか、Windows バイナリを生成可能な clang が Ubuntu 上に見当たらなかった(clang をビルドするには、MinGW gcc ではなく、clang が必要)などの理由により、これまでは VisualStudio を使って Windows 上でビルドしていました。

今回、以下の記事で llvm-mingw の存在を知り、無事カナディアンクロスビルドに成功しました。

続きを読む

2021年02月05日

職場の開発 PC が AMD Ryzen 9 5950X(16 コア 32 スレッド)RAM 32GB になったのですが、これまで 1 時間以上かかっていたビルドが数分で終わるようになったので劇的に効率が上がりました。Release ビルドならば 16 並列で CPU ほぼ 100% 使い切りメモリも足りているようです。Debug ビルドは 8 並列ぐらいまで落としてもメモリ不足で失敗しますが、何回か繰り返すと最後まで終わるので、デバッグ時なら許容範囲かなという感じです。LLVM の開発をするならば、できれば RAM は 64GB 欲しい所ですね。

新規にビルド環境を作ったので、その時のメモです。

続きを読む

2020年11月27日

Ubuntu 18.04 の APT でインストールできるパッケージでは、Clang のビルド要件を満たせなくなっているので、その解決方法です。

続きを読む

2020年11月19日

追記:本記事の内容は C++98 から有効であるとコメント欄にて教えていただきました。情報提供に感謝いたします。

GCC でコンパイル時に -Wall -Wextra の 2 オプションを付けるというのは非常に一般的です。この場合、以下のように未使用の関数引数には警告が出ます。
$ cat test.c
void f(int x) {}
void g(int x) {}

int main()
{
    f(10);
    g(10);
    return 0;
}

$ gcc -Wall -Wextra test.c
test.c: In function ‘f’:
test.c:1:12: warning: unused parameter ‘x’ [-Wunused-parameter]
 void f(int x) {}
            ^
test.c: In function ‘g’:
test.c:2:12: warning: unused parameter ‘x’ [-Wunused-parameter]
 void g(int x) {}
            ^
しかし、例えばコールバックとして渡す関数(ハンドラ)のように、引数を全部使わない関数というのはよくあります。

続きを読む

2020年11月17日

以前、「GCCの最適化による予期せぬ無限ループの発生」という記事を書きました。この時は -fno-builtin-malloc や __asm __volatile("":::"memory"); などで対策できました。

しかし今回、現状最新の GCC 10 で、memset、しかもナイーブな *(char *)s++ = (char)c; みたいな実装ではなく、NetBSD の本格的な実装のもので発生し、-fno-builtin や -fno-builtin-memset、-ffreestanding などでも抑制できず、-fno-tree-loop-distribute-patterns というあまり一般的ではないオプションが必要になりました。

これは一見 GCC のオプションが効いてない、バグのように思えますが、調べて見ると GCC の仕様に根差した問題であることがわかりました。

続きを読む

2020年08月26日

GNU ld(リンカ)には、EXCLUDE_FILE というフィルタ機能があり、特定のファイル(*.o オブジェクトファイルだけではなく、ライブラリの *.a アーカイブファイルも)を入力ファイルのワイルドカード指定から除外することができます。

この構文には単一セクションの場合は問題ありませんが、複数セクションを指定する場合に非直感的な仕様があることがわかったので紹介します。

続きを読む

2020年04月15日

RISC-V のベクトル拡張は現在策定中の仕様です。最新安定板はバージョン 0.8 で、一つ前は 0.7.1 でした。そのためインターネット上には古い情報と新しい情報が混在しています。

この記事もすぐに古くなると思いますが、開発版の 0.9.x ベースの GCC ツールチェーンの動作確認ができたので、シェルスクリプト化して公開します。

続きを読む

2019年09月13日

コンパクトな独自の libc を実装していて、GCC のテストを通したところ、WARNING: program timed out. が原因による FAIL が多発しました。調べた結果、非常に意外な結果だったのでメモします。

続きを読む

2019年04月22日

とある開発中のプロジェクトで、GCC/Clang のインラインアセンブラが意図しない不正コードを生成し、バグではないか?と調査しました。

その結果、これはどうやら正しい仕様らしい、しかし非常に間違いやすく混乱しやすいケースだと思ったのでメモしておきます。

解決策だけを先に言いますと、GCC/Clang のインラインアセンブラを、可能ならば常に 1 文に 1 命令のスタイルで記述するようにすれば、この類の混乱は避けられそうです。

続きを読む

2019年04月18日

Xilinx 社の ZynqMP 詳しくないのですが、Xilinx QEMU は PMU※1(qemu-system-microblazeel)ターゲットの QEMU と APU/RPU※2(qemu-system-aarch64)ターゲットの QEMU を別プロセスで 2 つ起動してエミュレーションを行う構成が存在します。

以前ビルドした Windows 版※3でも動作させることができたのでメモしておきます。

続きを読む

2019年01月18日

前回の記事では、Xilinx QEMU の Zynq UltraScale+ MPSoC ZCU102(ZynqMP)ターゲットの APU(AArch64 Cortex-A53 4 コア)上で Toppers fmp を動かしました。

今回は RPU(ARM Cortex-R5 2 コア)上で Toppers fmp を動かして見ます。
環境は前回の準備を前提としますが、今度は ARM のツールチェーンの準備が別途必要です。

続きを読む

2018年12月27日

以前の記事で Xilinx QEMU を Ubuntu 18.04 上でビルドしましたが、その QEMU を使って、Zynq UltraScale+ MPSoC(以後 ZynqMP) の APU パート、AArch64 (a53) 4 コアターゲットの Toppers FMP を動かして見ました。

Toppers も、QEMU と同じ Ubuntu Linux 環境でクロスビルドします。
何か所かハマったので、正解ルートだけではなく、あえてハマったポイントと回避策も記録として残しますので、少々冗長になります。

続きを読む

2018年12月14日

GNU ld には wrap という機能があります。これはリンク時に、未定義(Undefined)のシンボル foo を __wrap_foo として解決し、元のシンボルを __real_foo として解決するという機能です。これを利用すると、バイナリ提供のライブラリ関数を差し替えることが可能になります。

C での使用例はネット上にたくさん存在しますが、C++ の例がほとんど見つからなかったのでメモしておきます。

続きを読む

記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード