私はカスタムセクションにいくつかの構造体を保存し、それらの構造体を反復して内容を表示するCでこのPOCを持っています。LKMのELFセクションを使用
#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, \
.counter = 0, \
}; \
}while(0)
extern struct counter_info __start_counters;
extern struct counter_info __stop_counters;
int main(int argc, char **argv){
printf("Start %p\n", &__start_counters);
__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 %p\n", &__stop_counters);
return 0;
}
出力:
Name: c | Counter: 0.
Name: b | Counter: 0.
Name: a | Counter: 0.
期待通りの出力が、私は、カーネルモジュールのそれと同じことをやろうとしているされて
:
ハロー1.C
#include <linux/module.h>
#include <linux/kernel.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, \
.counter = 0, \
}; \
}while(0)
extern struct counter_info __start_counters;
extern struct counter_info __stop_counters;
int init_module(void){
__PUT_STUFF_IN_SECTION(a);
__PUT_STUFF_IN_SECTION(b);
__PUT_STUFF_IN_SECTION(c);
return 0;
}
void cleanup_module(void){
struct counter_info *iter = &__start_counters;
for(; iter < &__stop_counters; ++iter){
printk(KERN_INFO "Name: %s | Counter: %d.\n", iter->name, iter->counter);
}
}
メイクファイル:
obj-m += hello-1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
しかし、私はモジュールをコンパイルするとき、私はこれらの警告を得る:
WARNING: "__stop_counters" [/media/sf_procmon/procmon_kmodule/test/hello-1.ko] undefined!
WARNING: "__start_counters" [/media/sf_procmon/procmon_kmodule/test/hello-1.ko] undefined!
私の質問です:なぜ動作していないとどのように私はLKM内部のセクション属性を使用することが出来るのですか?
EDIT:
Makefileの
ccflags-y := -Wl,-Tlinkerscript.ld
obj-m += hello-1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
linkerscript.ld
SECTIONS
{
.rel.rodata.counters : {
PROVIDE(start_counters = .);
*(counters)
PROVIDE(stop_counters = .);
}
}
INSERT AFTER .text;
が、私は同じことを得続ける:私はこの答えInitialize global array of function pointers at either compile-time, or run-time before main()を見て、私は同じことをやってみました
警告。私はリンカスクリプトに何か問題があったかどうか、私の問題の解決策ではないかどうかは分かりません。EDIT:
私はそううまくいけば、誰かが私に回避策を与えることができ、私の質問を編集しています。コンパイル時に、いくつかの構造体が宣言され、データで埋められます。各構造体はブロック内で宣言されているので、名前でアクセスすることはできません。外に宣言することはできません。私はまた、コンパイルからコンパイルに変わる可能性のある構造体の正確な数を知らない。私が必要とするのは、それらすべてにアクセスする(それらを繰り返し実行する)方法です。構造体がセクションに保存されるか、他の魔法と一緒に保存されるかどうかは、実際には気にしません。
カーネルモジュールの例では、このような( ".name = #_name")のような前処理を使用していますが、このような使用を試みています( "__start_counters;")。これを行うには、これを元に戻す必要があります( "__counters_start")。 –
@PeterL。 '' '.name'''はセクション名とは関係ありません。 '' '.name''は構造体' '' counter_info''の単なる項目です。つまり、私のリンカスクリプトで '' '' start_counter'''にある単語を切り替えるべきだと思いますか? – alexandernst
おそらくカーネルローダーはこの属性をサポートしていません。カーネルモジュールの読み込みとプログラムの違いの1つは、前者が動的にカーネルにコードを追加していることです。新しいセクションを追加するのは遅すぎると思われます。 – ash