3

数年前、私はブログを読みました (今ではリンクは忘れ去られています)。以前の組織でファームウェアのパッチを開発する際に関数ポインターを多用している例を見たことさえあります。

しかし、セキュリティ上の理由や NDA の署名により、コードのコピーを入手できませんでした (そうせず、ベスト プラクティスに従っていることを誇りに思います)。

関数は次のような命名規則でコーディングされていることがわかりました。

filename_func_<version>_<minor_string>(arguments,other arguments)

同様のファイルがコード化され (パッチの一部)、ROM にフラッシュされます。関数が呼び出されると、パッチの場所から関数の新しい定義のアドレスが取得されます。

これに関するアイデア/詳細はありますか?

4

1 に答える 1

1

システムは、これを機能させるように設計する必要があります。

調整が必要なさまざまな側面があります。

  • 関数ポインタを変更する方法が必要です。
  • コードは、ポインターを介して関数を呼び出す必要があります。

詳細には複数の方法がありますが、最終的にはテーマのバリエーションになります。

/* Declaration of function pointer used to invoke the function */
extern int (*filename_func_ptr)(int arg1, char const *arg2);

/* Two versions of the function */
extern int filename_func_1_1(int arg1, char const *arg2);
extern int filename_func_1_2(int arg1, char const *arg2);

/* Definition of function pointer - pointing to version 1.1 of the function */
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_1;

/* Use of function pointer */
static void some_function(void)
{
    printf("%d\n", (*filename_func_ptr)(1, "pi"));
}

同じファイルで と の両方filename_func_1_1()を宣言することは決してないことに注意してください。filename_func_1_2()私が説明している効果は「まるで」です。

パッチを適用した後、どのような方法を選択しても、結果は次のように記述されているようになります。

int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_2;

新しいシンボルを取得するために、動的読み込み ( dlsym()、plusなど) で問題が発生する可能性があります。dlopen()これには、ライブラリを動的にロードするためのファイル名と、関数名を適切な関数へのポインターに変換する方法が必要です。

パッチ可能な各関数は、ポインターを介して均一に呼び出す必要があります。これにより、関数を置き換えることができます。動的 (共有) ライブラリで十分かどうかを検討してください (おそらくより単純になるため)。ファームウェアを使用している場合、おそらくその余裕はありません。

多様なインターフェイスを使用して複数の関数を処理する方法を検討する必要があります。ここに示すように単一のグローバル変数を使用するか、呼び出しごとに適切にキャストする必要があるジェネリック関数ポインター型を使用するか、共用体型を使用するか、ポインターを保持する構造体を使用するか、または ... 物事を整理する方法はたくさんあります。 .

于 2012-04-28T20:57:17.383 に答える