3

関数の(相対)アドレスに影響を与えたり、設定したり、定義したりする方法はありますか? 関数 abc() が常に OFFSET+0x0034C0 にあることを確認するために、リンカー スクリプト内に何らかの可能性があるかもしれません (ほんの一例です)。メモリ内の関数の場所を何らかの形で「制御」して、それらの場所をある種のパラメータ化したいと考えています。現在、x86 で gcc を使用する方法を探しています。ただし、実際のアプリケーションは組み込みデバイスで実行する必要があります。

よろしく

4

3 に答える 3

8

おそらく、gcc でリンカー スクリプト マジックを使用して実行できます。セクションの配置を定義する方法を確認してから、ソースにディレクティブを配置して、選択したセクションに関数を配置します。

ただし、オペレーティングシステムには...異議がある可能性があるため、x86マシンで機能するかどうかはまったくわかりません。これは、組み込みで直接使用するためのものです。

完全なオペレーティング システムでコードの場所を制御するポイントは何でしょうか?

于 2013-02-06T13:40:14.017 に答える
1

これに対する典型的な一般化された実装は、ベクトル テーブルです (パッチ テーブルと呼ばれることも聞いたことがあります)。

まず、C ファイルに関数を記述します。

void my_first_function(int){ /* do something */ }
void my_second_function(int){ /* do something */ }

次に、C ファイルで、テーブルのレイアウトを定義する構造体を作成します。

struct MyVectorTable
{
  void (*first_function)(int);
  int (*second_function)(float, char);

  // all the rest
};

次に、C ファイルで静的テーブルを作成します。

static struct MyVectorTable my_vector_table = {
  my_first_function,
  my_second_function,
};

最後に、アドレスを void* として公開します。

void* get_table_base_address(void) { return &my_vector_table; }

これで、ベース アドレスからのオフセットとしてすべての関数を取得できるはずです。

すべての関数に同じ呼び出しシグネチャがある場合は、構造体の代わりに関数ポインターの配列を使用することでこれを簡素化できます。ただし、配列と構造体の両方がポインターを保持するため、ポインターの計算は基本的に同じです。

これにより、リンカーを使用して特定のアドレスでパッチ テーブルを見つけることもできます。

于 2013-02-06T14:01:51.737 に答える
1

これを行う最善の方法は、IMO は、アンワインドが上で述べたように、関数をユーザー定義セクションに配置することです。myFunc関数を 4kByte 境界に配置する簡単な例を以下に示します。

リンカー スクリプトを変更して、メモリに新しいセクションを作成します。

/* .my_section will be the name of the section in the final executable */
.my_section : ALIGN (8)
{
    . = ALIGN (0x1000);

    KEEP(*(.mysection))    /* The section will be called ".mysection" in the
                              compiled translation unit (.obj) */

    . = ALIGN (8);
} >rom

次に、gcc のattribute機能を使用して、作成したばかりのセクションに関数を配置します。

void myFunc(void) __attribute__ ((section(".mysection"))); // The section name to use 
                                                           // here is ".mysection", 
                                                           // not ".my_section"

// Looks like you need to use __attribute__ along with function declaration, rather 
// than with the function definition, though I'm not sure why

void myFunc(void)
{
    // ...
}

ここで実行すると、 atではなくat addressのコードを保持するobjdump名前のセクションが表示されます。.my_sectionmyFunc0x20000x12e8

Disassembly of section .my_section:

000012e8 <myFunc-0xd18>:
        ...

00002000 <myFunc>:
    2000:       b508            push    {r3, lr}
    ...

このコードはCodesourcey gcc、ARM-Cortex のスイートで動作します。x86についてはよくわかりません...

于 2013-02-06T14:22:44.920 に答える