3

バイナリのセクション ( など) にいくつかの変数を格納し、それらを反復処理しようとして__attribute((__section__("counters")))いますが、そのセクションの開始方向を取得する方法が見つかりません。

GCC のドキュメントを読むと、(自動的に?) 2 つの変数が作成されていることがわかりまし__start_counters__stop_counters

私の質問は、セクションにいくつかの変数を保存し、それらの変数を取得するにはどうすればよいですか?

編集:

私が達成しようとしていることを示す最小限のコンパイル可能なコード。

#include <stdio.h>

char a, b, c;

struct counter_info {
    int counter;
    char *name;
} __attribute__((packed));

#define __PUT_STUFF_IN_SECTION(name)                    \
do{                                                     \
    static struct counter_info __counter_info_##name    \
    __attribute((__section__("counters")))              \
    __attribute((__used__)) = {                         \
        .name = #name,                                  \   <--------- this line causes *a lot of* errors, remove to actually compile the code
        .counter = 0,                                   \
    };                                                  \
}while(0)

extern struct counter_info __start_counters;
extern struct counter_info __stop_counters;

int main(int argc, char **argv){
    printf("Start!\n");

    __PUT_STUFF_IN_SECTION(a);
    __PUT_STUFF_IN_SECTION(b);
    __PUT_STUFF_IN_SECTION(c);

    struct counter_info *iter = &__start_counters;
    for(; iter < &__stop_counters; ++iter){
        printf("Name: %s | Counter: %d.\n", &iter->name, &iter->counter);
    }
    printf("End!\n");

    return 0;
}
4

3 に答える 3

2

コードをコンパイルすると、期待どおりに動作します。

--- foo.c       2013-09-06 19:43:28.025027688 +0200
+++ bar.c       2013-09-06 19:44:07.273028621 +0200
@@ -7,12 +7,12 @@
     char *name;
 } __attribute__((packed));

-#define __PUT_STUFF_IN_SECTION(name)                    \
+#define __PUT_STUFF_IN_SECTION(_name)                    \
 do{                                                     \
-    static struct counter_info __counter_info_##name    \
+    static struct counter_info __counter_info_##_name    \
     __attribute((__section__("counters")))              \
     __attribute((__used__)) = {                         \
-        .name = #name,                                  \
+        .name = #_name,                                  \
         .counter = 0,                                   \
     };                                                  \
 }while(0)
@@ -29,7 +29,7 @@

     struct counter_info *iter = &__start_counters;
     for(; iter < &__stop_counters; ++iter){
-        printf("Name: %s | Counter: %d.\n", &iter->name, &iter->counter);
+        printf("Name: %s | Counter: %d.\n", iter->name, iter->counter);
     }
     printf("End!\n");
于 2013-09-06T17:48:38.367 に答える
1

マニュアルの例はかなりまともです。この回答のために少し最小化しました:

char stack[10000] __attribute__ ((section ("STACK"))) = { 0 };

main()
{
    /* Initialize stack pointer */
    init_sp (stack + sizeof (stack));
}

参照するコードがstack「メモリ セグメントを反復処理する」必要がないstackことに注意してください。それは .

通常、変数にアクセスするために特別なことを知ったり、何かをしたりする必要はありません。それらが特定のセグメントに配置されているという事実は、言語の抽象化レベルの下にあるものであり、スコープ内のすべての変数は通常、通常どおり名前でアクセスされます。

于 2013-09-06T08:05:30.817 に答える
0

あなたはかなり正しいです。属性 with section はデータを正しいセクションに配置し、gcc (またはリンカー) が__startand__stopシンボルを作成します。

コードを投稿していないので、何が問題なのかはわかりません。代わりに、概念の実装を紹介します。コードは github にあります。

ELF、a.out、および Apple が MacOS でバイナリ形式と呼んでいるものについて、これを処理するコードがあります。そこにはテストコードもあります。

于 2013-09-06T08:05:42.177 に答える