我有这个 POC 可编译代码:
hello-1.c
#include <linux/module.h>
#include <linux/kernel.h>
char a, b, c;
asm(".section counters, \"aw\"");
typedef struct {
atomic_t counter;
char *name;
int a;
int b;
void *ff;
void *rf;
} __attribute__((packed)) counter_info_t;
#define __PUT_STUFF_IN_SECTION(_name) \
do{ \
static counter_info_t __counter_info_##_name \
__attribute((used, section("counters"))) = { \
.counter = ATOMIC_INIT(0), \
.name = #_name, \
.a = 0, \
.b = 0, \
.ff = init_module, \
.rf = init_module, \
}; \
}while(0)
extern counter_info_t __start_counters[];
extern counter_info_t __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){
counter_info_t *iter = __start_counters;
printk(KERN_INFO "Start %p\n", &__start_counters);
for(; iter < __stop_counters; ++iter){
printk(KERN_INFO "Name: %s.\n", iter->name);
}
printk(KERN_INFO "End %p\n", &__stop_counters);
printk(KERN_INFO "Goodbye world!\n");
}
linkerscript.ld
SECTIONS
{
counters : {
__start_counters = . ;
*(counters)
__stop_counters = . ;
}
}
Makefile
obj-m += hello.o
hello-y += hello-1.o
ldflags-y += -T$(M)/linkerscript.ld
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
这段代码所做的是将一些结构放在一个部分中,然后遍历这些结构,打印每个结构的名称。
请注意,代码原样会失败,打印错误的数据。无论如何,从结构中删除一个成员(例如 member b
)模块将开始正常工作。
我的问题是:为什么会失败?为什么++iter
当结构有 6 个成员时不会执行正确的指针操作,但它会在 5 个成员下正常工作?
重现步骤:make
, sudo insmod hello.ko
, sudo rmmod hello
,dmesg
编辑:添加 readelf 输出
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 2808 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 15
Section header string table index: 10
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000088 0000000000000000 AX 0 0 16
[ 2] .rela.text RELA 0000000000000000 00000838
0000000000000168 0000000000000018 11 1 8
[ 3] .data PROGBITS 0000000000000000 000000c8
0000000000000000 0000000000000000 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 000000c8
0000000000000003 0000000000000000 WA 0 0 4
[ 5] counters PROGBITS 0000000000000000 000000e0
00000000000000a4 0000000000000000 WA 0 0 32
[ 6] .relacounters RELA 0000000000000000 000009a0
00000000000000d8 0000000000000018 11 5 8
[ 7] .rodata.str1.1 PROGBITS 0000000000000000 00000184
000000000000003b 0000000000000001 AMS 0 0 1
[ 8] .comment PROGBITS 0000000000000000 000001bf
000000000000002b 0000000000000001 MS 0 0 1
[ 9] .note.GNU-stack PROGBITS 0000000000000000 000001ea
0000000000000000 0000000000000000 0 0 1
[10] .shstrtab STRTAB 0000000000000000 00000a78
0000000000000079 0000000000000000 0 0 1
[11] .symtab SYMTAB 0000000000000000 00000598
00000000000001f8 0000000000000018 12 12 8
[12] .strtab STRTAB 0000000000000000 00000790
00000000000000a4 0000000000000000 0 0 1
[13] __mcount_loc PROGBITS 0000000000000000 00000eb8
0000000000000010 0000000000000008 A 0 0 8
[14] .rela__mcount_loc RELA 0000000000000000 00000ec8
0000000000000030 0000000000000018 11 13 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
Relocation section '.rela.text' at offset 0x838 contains 15 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000001 000d00000002 R_X86_64_PC32 0000000000000000 __fentry__ - 4
000000000011 000d00000002 R_X86_64_PC32 0000000000000000 __fentry__ - 4
00000000001b 000f0000000b R_X86_64_32S 0000000000000000 __start_counters + 0
000000000022 00060000000b R_X86_64_32S 0000000000000000 .rodata.str1.1 + 0
00000000002b 001000000002 R_X86_64_PC32 0000000000000000 printk - 4
000000000032 000f0000000b R_X86_64_32S 0000000000000000 __start_counters + 0
000000000038 00110000000b R_X86_64_32S 0000000000000000 __stop_counters + 0
000000000041 00110000000b R_X86_64_32S 0000000000000000 __stop_counters + 0
000000000048 00060000000b R_X86_64_32S 0000000000000000 .rodata.str1.1 + c
00000000004f 001000000002 R_X86_64_PC32 0000000000000000 printk - 4
000000000056 00060000000b R_X86_64_32S 0000000000000000 .rodata.str1.1 + 16
00000000005d 001000000002 R_X86_64_PC32 0000000000000000 printk - 4
000000000070 00060000000b R_X86_64_32S 0000000000000000 .rodata.str1.1 + 28
000000000079 001000000002 R_X86_64_PC32 0000000000000000 printk - 4
000000000080 00110000000b R_X86_64_32S 0000000000000000 __stop_counters + 0
Relocation section '.relacounters' at offset 0x9a0 contains 9 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000004 000600000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 35
000000000014 000c00000001 R_X86_64_64 0000000000000000 init_module + 0
00000000001c 000c00000001 R_X86_64_64 0000000000000000 init_module + 0
000000000044 000600000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 37
000000000054 000c00000001 R_X86_64_64 0000000000000000 init_module + 0
00000000005c 000c00000001 R_X86_64_64 0000000000000000 init_module + 0
000000000084 000600000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 39
000000000094 000c00000001 R_X86_64_64 0000000000000000 init_module + 0
00000000009c 000c00000001 R_X86_64_64 0000000000000000 init_module + 0
Relocation section '.rela__mcount_loc' at offset 0xec8 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000200000001 R_X86_64_64 0000000000000000 .text + 0
000000000008 000200000001 R_X86_64_64 0000000000000000 .text + 10
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table '.symtab' contains 21 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello-1.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 36 OBJECT LOCAL DEFAULT 5 __counter_info_a.14513
8: 0000000000000040 36 OBJECT LOCAL DEFAULT 5 __counter_info_b.14514
9: 0000000000000080 36 OBJECT LOCAL DEFAULT 5 __counter_info_c.14515
10: 0000000000000000 0 SECTION LOCAL DEFAULT 9
11: 0000000000000000 0 SECTION LOCAL DEFAULT 8
12: 0000000000000000 13 FUNC GLOBAL DEFAULT 1 init_module
13: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __fentry__
14: 0000000000000010 120 FUNC GLOBAL DEFAULT 1 cleanup_module
15: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __start_counters
16: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printk
17: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __stop_counters
18: 0000000000000000 1 OBJECT GLOBAL DEFAULT 4 c
19: 0000000000000001 1 OBJECT GLOBAL DEFAULT 4 b
20: 0000000000000002 1 OBJECT GLOBAL DEFAULT 4 a
No version information found in this file.