Skip to content

Instantly share code, notes, and snippets.

@tenpoku1000
Last active May 1, 2024 07:52
Show Gist options
  • Save tenpoku1000/9878188f4c8ecd1a5db1d16549f45fc9 to your computer and use it in GitHub Desktop.
Save tenpoku1000/9878188f4c8ecd1a5db1d16549f45fc9 to your computer and use it in GitHub Desktop.
自作派の人のためのコンパイラ関連規格のメモ

自作派の人のためのコンパイラ関連規格のメモ

2024/05/01 更新

この記事は、自作OS Advent Calendar 2017の 12/4 の記事として書かれました。C 言語と JavaScript、それに両者を繋ぐ役割を持つ Web IDL についてのメモです。

主に、仕様書のダウンロード・サイトなどの URL を集めてみました。この他の URL は、以下でブックマークを公開していますので、興味がある方は参照してみてください。

データに着目したコンパイラの処理の流れ

  1. ソースコード(UTF-8 など)
  2. トークン列
  3. 解析木または抽象構文木
  4. 中間言語(WebAssembly など)
  5. アセンブリ
  6. オブジェクト・ファイル(PE, ELF など)
  7. コード署名が付加されたオブジェクト・ファイル(PE など)

Unicode の書籍・規格書

ソースコードを Unicode の符号化方式の一つ、UTF-8 への対応を行う際に参考になる資料は以下の通りです。

自作OS Advent Calendar 2017向けに書いた記事では、Unicode の概要を簡単に説明しています。タイトルは UTF-32 となっていますが、UTF-8 でも参考になると思います。

C 言語を選択する理由と、仕様に関する情報

C 言語を選択する理由ですが、特定の企業に所有されておらず、国際標準規格であることが利点です。また、言語仕様が比較的小さく、個人でも実装可能な範囲に収まっていると思います。スクリプト言語を選択しないのは、スクリプト言語のパッケージが C の拡張を含む場合、POSIX API に依存していることも多く、移植性が低いです。同様の理由で、Java VM や .NET の言語も採用できません。

仕様に関する主な情報は以下の通りです。

Language Server Protocol

コンパイラが Language Server Protocol のサーバを実装することで、Language Server Protocol のクライアントを実装している統合開発環境(IDE)やテキストエディタで、コード補完などの機能が使えるようになります。

WebAssembly

中間言語として、WebAssembly や WebAssembly を拡張したものを利用することを利用することを検討しています。WebAssembly は Web ブラウザだけでなく、組み込み環境向けにも使われることが想定されています。

アセンブリ

アセンブリ言語の仕様として有名なのは、AT&T 構文と Intel 構文です(AT&T 記法・Intel 記法とも呼びます)。

コンパイラが生成するアセンブリ言語の関数呼び出しなどのルールを定めた仕様は、ABI(Application Binary Interface)と呼びます。x64 の UEFI では Microsoft の x64 呼び出し規約が採用されています。

Microsoft の x64 呼び出し規約

Linux 等の POSIX 系の環境の System V ABI

リンカ

x64 の場合、オブジェクト・ファイルは PE32+ か ELF であることが多いです。UEFI では PE32+ が採用されています。

UEFI や Windows のオブジェクト・ファイル形式:PE32+

Linux 等の POSIX 系の環境のオブジェクト・ファイル形式:ELF

PE32+ のコード署名

UEFI セキュアブートを有効化した状態で UEFI アプリを実行可能にするためには、UEFI アプリである PE32+ オブジェクト・ファイルに Microsoft のコード署名を付加する必要があります。2017/12/04 現在、Microsoft のコード署名には EV 証明書が必要です。EV 証明書の維持費は高額ですし、EV 証明書の取得は、企業が対象です。EV 証明書の取得のために企業を設立するのは現実的な選択肢ではありません。

上述の制約は、Microsoft のコード署名が付加された shim ブートローダを利用することで、回避することが可能です。

shim ブートローダは、UEFI の NVRAM(Non-Volatile RAM:不揮発性 RAM)に格納される UEFI 変数に、MOK(Machine Owner Keys:マシン所有者鍵)という鍵を MokManager UEFI アプリで登録する必要があり、shim ブートローダから起動される UEFI アプリは、MOK でコード署名されている必要があります。

MOK の構造は、次の「Authenticode 署名」で説明します。

Authenticode 署名

PE32+ オブジェクト・ファイルに格納されている Authenticode 署名は、RFC 2315 で規定されている PKCS #7 の SignedData に、ASN.1(Abstract Syntax Notation One)形式でファイルに格納されています。

RFC 2315 : 9.1 SignedData type

   The signed-data content type shall have ASN.1 type SignedData:

   SignedData ::= SEQUENCE {
     version Version,
     digestAlgorithms DigestAlgorithmIdentifiers,
     contentInfo ContentInfo,
     certificates
       [0] IMPLICIT ExtendedCertificatesAndCertificates
          OPTIONAL,
     crls
       [1] IMPLICIT CertificateRevocationLists OPTIONAL,
     signerInfos SignerInfos }

PKCS #7 の SignedData の certificates には署名に関する X.509 証明書(これも ASN.1 形式です)を格納します。本稿では、上述の MOK を格納します。signerInfos には署名群(コード署名など)を格納します。

X.509 証明書の生成や、コード署名に必要な暗号化アルゴリズムは、比較的早く陳腐化するので本稿では割愛します。コード署名サービスを利用することで、Windows アプリを配布する場合にセキュリティ警告表示を抑制することができます。

ASN.1 の参考書

X.509 の仕様書

テストに使えそうなファイル形式の仕様(TAP)

エラーメッセージの出力に使えそうな、ログ出力の仕様(LTSV)

デバッグ情報

2017/12/04 現在、LLVM プロジェクトで公開されている PDB のドキュメントは、未完成です。

GCC/Clang などで使われている DWARF

MSVC で使われている PDB/CodeView

Windows の 64 ビット・アプリの構造化例外処理

構造化例外処理は、Linux 等の POSIX 系の環境の signal に相当するものです。コンパイラやリンカが例外処理用の情報を PE32+ オブジェクト・ファイルに付加出来ることが必要です。

Debug Adapter Protocol

Build Server Protocol

セキュリティ関連

コンパイラやリンカなどで実装が必要なセキュリティ関連の機能を集めてみました。

Intel MPX

2024/05/01 現在、Alder Lake や Raptor Lake 等のクライアント向け CPU では Intel MPX は実装されなくなっています。

Windows の 32 ビット・アプリの構造化例外処理のセキュリティ対策

Windows の /GS(バッファーのセキュリティ チェック)

Windows の Control Flow Guard

JavaScript

JavaScript の言語仕様は、ECMA-262 で規定されています。完全に和訳された JIS 規格票は無く、規格書を和訳した書籍が過去に出版されたことがあります。

asm.js は WebAssembly が登場する前に、JavaScript の言語仕様に制限を設けることで、C/C++ など JavaScript 以外の言語で書かれたソースコードを asm.js に変換するために作られた仕様です。Web ブラウザ上で実行する際に、WebAssembly よりも asm.js の構文解析に要する時間がかかると言われています。asm.js に対応していない環境では、通常の JavaScript として解釈・実行されます。

JavaScript のデバッグ

JavaScript のデバッガは、ブラウザ・エンジン毎にプロトコルが異なりますが、これを統合する動きがあるようです。

Source Map

JavaScript のソースコードをコンパイルした結果、コンパイルする前のソースコードとの行の対応などを確認したいことがあります。Source Map を使うと良いようです。WebAssembly のサイトでも、Source Map について言及されています。

HAR ファイル

Web ブラウザと Web サイトとの通信内容を保存してデバッグに役立てるためのファイル形式です。2024/05/01 現在、標準仕様としては発表されず、放棄されているようです。

抽象構文木:ESTree

ツールなどから、プログラムの構造を操作したいことがあります。ESTree は JavaScript の抽象構文木を表現するコミュニティ標準です。

抽象構文木のバイナリ版:Binary AST と BinJs

WebAssembly の JavaScript 専用版みたいなものです。WebAssembly や asm.js と異なり、従来からの JavaScript を高速化する試みだと思われます。

解析木:JavaScript CST(Concrete Syntax Tree)

JavaScript の抽象構文木を表現する ESTree などに対して、括弧や空白などを含む解析木を表現する仕様である JavaScript CST が考案されていたようですが、仕様の策定は断念されたようです。

Web IDL

Web IDL は、C 言語と JavaScript の両者を繋ぐ役割があります。Web ブラウザを実装するなら、Web IDL コンパイラが使えるようになっていた方が良いでしょう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment