rt-thread中的XXX_EXPORT()测试

本文介绍了一种在C语言中实现自定义系统调用表的方法,通过定义宏和结构体来注册和调用系统级函数。使用GCC链接器脚本进行符号定位,实现了动态加载和调用的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试代码:

#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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值