测试代码:
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
typedef long (*syscall_func)(void);
typedef struct st_syscall
{
const char* name;
const char* desc;
syscall_func func;
}syscall_t;
extern syscall_t _syscall_table_begin, _syscall_table_end;
#define SECTION(x) \
__attribute__((section(x)))
#define FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
const syscall_t __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define CMD_EXPORT(command, desc) \
FUNCTION_EXPORT_CMD(command, _cmd_##command, desc)
static void func1(void)
{
printf("this is function1\n");
}
CMD_EXPORT(func1, test1);
static void func2(void)
{
printf("this is function2\n");
}
CMD_EXPORT(func2, test2);
static void func3(void)
{
printf("this is function3\n");
}
CMD_EXPORT(func3, test3);
int main(void)
{
const syscall_t *call_ptr = &_syscall_table_begin;
for (;call_ptr < &_syscall_table_end;call_ptr++)
{
printf ("call_ptr: %p\n", call_ptr);
printf ("name=%s,desc=%s\n", call_ptr->name, call_ptr->desc);
call_ptr->func();
}
return 0;
}
执行命令生成xxx.lds文件,如:
ld --verbose > sss.lds
获取内置lds脚本,并在:
把最前的
==============
多行删除掉, 也要删除最后
==============
一行.
__bss_start = .;
之前添加以下内容:
_syscall_table_begin = .;
FSymTab :
{
*(FSymTab);
}
.align = 4;
_syscall_table_end = .;
保存退出。
Makefile文件:
all:
gcc main.c -Wl,-Tsss.lds
gcc -c main.c
objdump -t main.o
clean:
rm main.o test
运行结果:
$ make
gcc main.c -Wl,-Tsss.lds
gcc -c main.c
objdump -t main.o
main.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 main.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .rodata 00000000 .rodata
00000000 l F .text 00000019 func1
00000000 l d .rodata.name 00000000 .rodata.name
00000000 l d FSymTab 00000000 FSymTab
00000019 l F .text 00000019 func2
00000032 l F .text 00000019 func3
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .eh_frame 00000000 .eh_frame
00000000 l d .comment 00000000 .comment
00000000 *UND* 00000000 puts
00000000 g O .rodata.name 0000000b __fsym__cmd_func1_name
0000000c g O .rodata.name 00000006 __fsym__cmd_func1_desc
00000000 g O FSymTab 0000000c __fsym__cmd_func1
00000014 g O .rodata.name 0000000b __fsym__cmd_func2_name
00000020 g O .rodata.name 00000006 __fsym__cmd_func2_desc
0000000c g O FSymTab 0000000c __fsym__cmd_func2
00000028 g O .rodata.name 0000000b __fsym__cmd_func3_name
00000034 g O .rodata.name 00000006 __fsym__cmd_func3_desc
00000018 g O FSymTab 0000000c __fsym__cmd_func3
0000004b g F .text 0000006c main
00000000 *UND* 00000000 _syscall_table_begin
00000000 *UND* 00000000 printf
00000000 *UND* 00000000 _syscall_table_end
$ ./a.out
call_ptr: 0x804a024
name=_cmd_func1,desc=test1
this is function1
call_ptr: 0x804a030
name=_cmd_func2,desc=test2
this is function2
call_ptr: 0x804a03c
name=_cmd_func3,desc=test3
this is function3