当前位置: 首页 > news >正文

Windows GCC修改链接脚本文件实现section块存储函数

在单片机C语言中,常使用section定义函数块或变量块。

那么,在Windows系统上如何实现呢?有参考的文章,但是也踩了不少坑。

1、编写C代码

编写c文件,代码参考如下:

/* 将函数加入某一个section段内,并按顺序调用*/
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>typedef void (*myown_call)(void);    // 定义函数指针类型extern myown_call _myown_start;    // 函数块头
extern myown_call _myown_end;      // 函数块尾// 定义.myown块
#define _init __attribute__((unused, section(".myown")))
#define func_init(func) myown_call _fn_##func _init = funcstatic void mspec1(void)
{printf("mspec1!\n");
}static void mspec2(void)
{printf("mspec2!\n");
}static void mspec3(void)
{printf("mspec3!\n");
}func_init(mspec1);
func_init(mspec2);
func_init(mspec3);/* func_init()作用相当于如下语句:
static myown_call mc1  __attribute__((unused, section(".myown"))) = mspec1;
static myown_call mc2  __attribute__((unused, section(".myown"))) = mspec2;
static myown_call mc3  __attribute__((unused, section(".myown"))) = mspec3;
*/void do_initcalls(void)
{myown_call *call_ptr = &_myown_start;do {fprintf (stderr, "call_ptr: %p\n", call_ptr);(*call_ptr)();++call_ptr;} while (call_ptr < &_myown_end);
}int main(void)
{do_initcalls();return 0;
}

2、修改GCC默认链接脚本

首先,将默认的链接脚本另存一个新文件,可在终端输入命令:

ld --verbose >test.lds

将会生成一个test.lds文件。

首先,要将lds转换为utf-8编码格式,否则会报告错误:

C:/Program Files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe:xx.lds:1: ignoring invalid character `\377' in expression
C:/Program Files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe:xx.lds:1: ignoring invalid character `\376' in expression
C:/Program Files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe:xx.lds:1: ignoring invalid character `\000' in expression
C:/Program Files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe:xx.lds:1: syntax error
collect2.exe: error: ld returned 1 exit status

其次,要删除文件前后的“=======================”内容,

否则报告错误:lds:1: syntax error

 最后,在“__bss_start__ = . ;”前面添加:

    _myown_start = .;*(.myown)_myown_end = .;

最终如下图所示。 

3、编译新的链接脚本

编译新的链接脚本,如:

gcc -T test.lds xxx.c -o xxx.exe

也可以修改VScode的tasks.json脚本:

 到C文件界面,按F5开始调试,成功输出:

call_ptr: 0000000000407000
mspec1!
call_ptr: 0000000000407008
mspec2!
call_ptr: 0000000000407010
mspec3!

参考链接:GCC中初始化函数是怎样被处理的?-腾讯云开发者社区-腾讯云

gcc s.lds 使用方法_gcc lds-CSDN博客

Windows 中用 gcc 编译并引用链接脚本中定义的变量时的注意点_c链接脚本中定义变量-CSDN博客 .lds链接脚本以及编译流程分析_.lds文件编译-CSDN博客

http://www.dtcms.com/a/290083.html

相关文章:

  • LVS 集群技术基础
  • docker--挂载
  • Docker安装Elasticsearch 7.17.0和Kibana 7.17.0并配置基础安全
  • 悬镜安全将受邀参加2025开放原子开源生态大会
  • Curtain e-locker 易锁防泄密:无需网络隔离,实现安全与效率并存
  • 量子生成对抗网络:量子计算与生成模型的融合革命
  • uni-api交互反馈组件(showToast)的用法
  • 宝塔面板Nginx报错: IP+端口可以直接从访问,反向代理之后就504了 Gateway Time-out
  • 农村供水智慧化管理系统:从精准监测到智能调度,破解农村用水安全与效率难题
  • MySQL 事务死锁排查:从日志分析到解决实战
  • 某日在某个月份中不存在导致软件出现异常的问题排查(判断闰年以及月份中的天数,附完整源码)
  • 低代码平台能否完全取代传统前端开发
  • Bun v1.2.19发布,node_modules隔离,sql比node快6倍
  • MySQL:表的增删查改
  • 【跨国数仓迁移最佳实践2】MaxCompute SQL执行引擎对复杂类型处理全面重构,保障客户从BigQuery平滑迁移
  • VUE如何设置语音
  • 【实践篇】基于.venv 的 ComfyUI 环境同配置迁移:pyvenv.cfg 路径修改法
  • leetcode-sql-627变更性别
  • 植物根茎切片图像处理与分析系统开发
  • 【大模型】结构化提示词:让AI高效完成复杂任务的“编程语言”
  • 虚拟机扩展磁盘容量后扩展分区大小
  • 部署 Zabbix 企业级分布式监控
  • 【图像处理基石】什么是相机的内外参数?
  • 在Windows Server 2012 R2中安装与配置IIS服务并部署mssql靶机教程
  • 在Web API 开发中践行Security by Default原则
  • 【操作篇】群晖NAS用root权限直接访问系统分区文件
  • 4x4矩阵教程
  • channel_up和lane_up
  • OpenLayers 入门指南【三】:API概要
  • MetaGPT源码剖析(三):多智能体系统的 “智能角色“ 核心实现——Role类