Simicsではプログラムがあるポイントに差し掛かったり、あるアドレスにアクセスした時に
スクリプトを起動するという仕掛けを組むことができます
これを活用するとあるI/Oやメモリを読みに来たときに正常・異常任意の値を与えたり
サイクル数の計測やメモリリークの検出など、様々な応用も可能です
これはSIM_breakpoint と SIM_hap_add_callback_index というAPIを使用します
ブレイクポイントの設定は該当ブレイクポイントに対し Hap Callbackという物を設定する事で
プログラムの実行を停止せず、 Hap Callbackで指定したスクリプト関数を呼び出す処理を
行います
ではまずSIM_Breakpointの使い方です
breakpoint_id_t
SIM_breakpoint(conf_object_t *obj,
breakpoint_kind_t kind,
access_t access,
uint64 address,
uint64 length,
breakpoint_flag_t flags);
第1パラメータのオブジェクトですが、メモリにブレイクをかけるならメモリオブジェクトを
CPUが命令をフェッチしたときにブレイクしたいならCPUのコンテキストを指定します
第2パラメータkindには以下のように定義されたenumが使用できます
メモリブレイクのときはphysical, CPUでブレイクするときはVirtualですね
typedef enum {
Sim_Break_Physical = 0,
Sim_Break_Virtual = 1,
Sim_Break_Linear = 2 /* x86 only */
} breakpoint_kind_t;
第3パラメータ access では以下の中から選択してください
メモリのときはRead又はWrite CPUブレイクならExecuteです
typedef enum {
Sim_Access_Read = 1,
Sim_Access_Write = 2,
Sim_Access_Execute = 4
} access_t;
l第5パラメータength ではバイト数でアクセスサイズを指定します。
0を指定したときは指定アドレススペース全てが対象となります
l第6パラメータには以下のフラグがORで指定できます
typedef enum breakpoint_flag {
Sim_Breakpoint_Temporary = 1,
Sim_Breakpoint_Simulation = 2,
Sim_Breakpoint_Private = 4
} breakpoint_flag_t;
SIM_Breakpint_Temporary はブレイクポイントにヒットしたら自動的にその
ブレイクポイントは削除される事を意味してます
SIM_Breakpint_Simulation とSim_Breakpint_Privateはどちらもlist-breakpoint
コマンドなどで表示されないブレイクポイントとなり、Simicsコンソールのコマンドなどで
削除する事もできなくなります
では使用例のPythonスクリプトです、まずはメモリ用
bp_number = SIM_breakpoint(memspace,
Sim_Break_Physical,
Sim_Access_Write,
addr,
1, # 1 byte access
Sim_Breakpoint_Simulation)
SIM_hap_add_callback_index("Core_Breakpoint_Memop",
memory_breakpoint_callback,
(addr,andbits,orbits),
bp_number)
次はプログラムのあるポイント。ここではCPUのlr レジスタ、つまり関数から戻るところに
ブレイクをかけHap Callbackを設定します
tbp_number = SIM_breakpoint(conf.board.cpu[1].current_context ,
Sim_Break_Virtual,
Sim_Access_Write,
conf.board.cpu[1].lr,
4,
Sim_Breakpoint_Temporary)
SIM_hap_add_callback_index("Core_Breakpoint_Memop",
func_breakpoint_callback,
(count,tbp_number),
bp_number)
これを使ってどんな事ができるかは、次回