Skip to content

Plan 9 Cコンパイラのincompatible type signatureを調べる

This content is a draft and will not be included in production builds.

incompatible type signatures <sig1>(<file1>) and <sig2>(<file2>) for <name>
process_responder: incompatible type signatures 1d502cf7(ciphers.8) and 34448947(ocsp.8) for SSL_CTX_new

このエラーはローダでリンクする時に型シグネチャが異なると発生する。

8l/obj.cldobj は、通常のオブジェクトファイルならそのまま読む。arファイルのマジックナンバーならアーカイブとして読む。

sig1: 参照する側で計算したシグネチャ
file1: 参照する側のソースファイル名
sig2: アーカイブに含まれているシグネチャ
file2: アーカイブとなったソースファイル名
name: 関数名

参照する側のシグネチャはローダ側で計算しているものではない。最初に参照した時、sig2が0でなければその値が使われ続ける。

nm -T ciphers.8 ocsp.8 すると確かにシグネチャが違う

pcc -Tオプションはそのまま 8c に渡されて 8c -Tを実行する。

8cでは、-Tオプションがある場合、シンボル出力時にASIGNAME形式で書き出す。与えられなければANAMEでシグネチャがない。この処理は 8c/swt.czname で行う。

  • -Tが与えられていて、
  • グローバル(extern)で、
  • 1回だけ(Sym.sig != SIGDONE)
ASIGNAME(2byte) sig(4byte) type(1byte) sym(1byte) name... '\0'
ANAME(2byte) type(1byte) sym(1byte) name... '\0'
type
D_BRANCH = 60,
D_EXTERN = 61,
D_STATIC = 62,
D_AUTO = 63,
D_PARAM = 64,
D_CONST = 65,
D_FCONST = 66,
D_SCONST = 67,
D_ADDR = 68,

Sym*はどこで構築している?→ cc/lex.clookup から syminit

Sym.symとは?sig? SIGINTERNのようなもの。

cc/dcl.csign(Sym *)でシグネチャを計算する。実際は cc/dcl.csignature(Type *)