OUTPUT_FORMAT("elf32-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SECTIONS
{
. = 0x80100000;
.text:
{
_ftext = . ;
*(.text)
*(.rodata)
*(.rodata1)
*(.reginfo)
*(.init)
*(.stub)
*(.gnu.warning)
}=0
_etext = .;
PROVIDE (etext = .);
.fini: { *(.fini) } =0
.data:
{
_fdata = . ;
*(.data)
CONSTRUCTORS
}
.data1 : { *(.data1) }
.ctors :
{
__CTOR_LIST__ = .;
LONG((__CTOR_END__ -__CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
__CTOR_END__ = .;
}
.dtors :
{
__DTOR_LIST__ = .;
LONG((__DTOR_END__ -__DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
__DTOR_END__ = .;
}
_gp = ALIGN(16) + 0x7ff0;
.got :
{
*(.got.plt) *(.got)
}
.sdata : { *(.sdata) }
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
_fbss = .;
.sbss : { *(.sbss) *(.scommon) }
.bss :
{
*(.dynbss)
*(.bss)
*(COMMON)
}
. = ALIGN(16);
__bss_end = .;
_end = .;__end = .; end = .;
PROVIDE (end = .);
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.debug 0 : { *(.debug) }
.debug_srcinfo 0 : {*(.debug_srcinfo) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : {*(.debug_pubnames) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.line 0 : { *(.line) }
.gptab.sdata : {*(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : { *(.gptab.bss)*(.gptab.sbss) }
}
下面逐句解释。
OUTPUT_FORMAT("elf32-tradlittlemips")
OUTPUT_ARCH(mips)
OUTPUT_FORMAT 和 OUTPUT_ARCH 都是 ld 脚本的保留字命令。
OUTPUT_FORMAT 说明输出二进制文件的格式。
OUTPUT_ARCH 说明输出文件在平台。
ENTRY(_start)
ENTRY 命令的作用是,将后面括号中的符号值设置成入口地址。入口地址(entry point)的定义是这样的──进程执行的第一条用户空间的指令在进程地址空间中的地址。
ld 有多种方法设置进程入口地址,通常它按以下顺序:(编号越前, 优先级越高)
1. ld命令行的-e选项
2. 连接脚本的 ENTRY(SYMBOL) 命令
3. 如果定义了 start 符号, 使用 start 符号值
4. 如果存在 .text section, 使用 .text section 的第一字节的位置值
5. 使用值 0
SECTIONS{
然后,接下来是一大段的SECTIONS,对应的右大括号直到脚本的末尾。
SECTIONS 命令告诉 ld 如何把输入文件的sections 映射到输出文件的各个section:即是如何将输入section 合为输出 section;如何把输出 section 放入程序地址空间 (VMA) 和进程地址空间 (LMA) 。该命令格式如下:
SECTIONS
{
….
}
. = 0x80100000;
这句把定位器符号置为0x80100000 (若不指定,则该符号的初始值为 0)。
.是一个特殊的符号,它是定位器,一个位置指针,指向程序地址空间内的某位置(或某section内的偏移,如果它在SECTIONS命令内的某section描述内),该符号只能在SECTIONS命令内使用。
.text :
{
_ftext = . ;
*(.text)
*(.rodata)
*(.rodata1)
*(.reginfo)
*(.init)
*(.stub)
*(.gnu.warning)
} =0
.text : 表示text段开始。
_ftext
*(.text) 将所有(*符号代表任意输入文件)输入文件的.text section合并成一个.text section, 该section的地址由定位器符号的值指定, 即0x80100000.
*(.rodata)
*(.rodata1)
*(.reginfo)
*(.init)
*(.stub)
*(.gnu.warning)
} =0 表示合并时留下的空隙用 0 填充;
_etext = .;
PROVIDE (etext = .);
_etext = .; 我们看到,很多变量都定义成等于这个 . 符,实际上这个符号所代表的值是在变化的,随着越往后走,值越增加,根据前面填充的多少自动往后加。
PROVIDE关键字用于定义这类符号:在目标文件内被引用,但没有在任何目标文件内被定义的符号。
这里就定义了一个etext 符号,当目标文件内引用了etext符号,却没有定义它时,etext符号对应的地址被定义为.text section 之后的第一个字节的地址。
.fini : { *(.fini) } =0
意思与前面一样,但 fini 这名字是哪个段,我还搞不太清楚(???)。
.data :
{
_fdata = . ;
*(.data)
CONSTRUCTORS
}
.data1 : { *(.data1) }
数据段终于来到了,意思很容易理解的了。
CONSTRUCTORS 是一个保留字命令。与 c++ 内的(全局对象的)构造函数和(全局对像的)析构函数相关。
.ctors :
{
__CTOR_LIST__= .;
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
__CTOR_END__ =.;
}
.dtors :
{
__DTOR_LIST__= .;
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
__DTOR_END__ =.;
}
对于支持任意section名的目标文件格式,比如COFF、ELF格式,GNU C++将全局构造和全局析构信息分别放入 .ctors section 和 .dtors section 内
当 连接器生成的目标文件格式不支持任意section名字时,比如说ECOFF、XCOFF格式,连接器将通过名字来识别全局构造和全局析构,对于这些文件 格式,连接器把与全局构造和全局析构的相关信息放入出现CONSTRUCTORS 关键字的输出section内。
符号__CTORS_LIST__表示全局构造信息的的开始处,__CTORS_END__表示全局构造信息的结束处。
符号__DTORS_LIST__表示全局构造信息的的开始处,__DTORS_END__表示全局构造信息的结束处。
这两块信息的开始处是一字长的信息,表示该块信息有多少项数据,然后以值为零的一字长数据结束。
一般来说,GNU C++在函数__main内安排全局构造代码的运行,而__main函数被初始化代码(在main函数调用之前执行)调用。
_gp = ALIGN(16) + 0x7ff0;
_gp是一个重要的全局变量,好像是用作全局引用的一个指针。
.got :
{
*(.got.plt) *(.got)
}
.sdata : { *(.sdata) }
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
意义类似。
_edata = .;
PROVIDE (edata = .);
意义与前面的 etext 类似。edata 符号也较为重要。
__bss_start = .;
_fbss = .;
.sbss : { *(.sbss) *(.scommon) }
.bss :
{
*(.dynbss)
*(.bss)
*(COMMON)
}
. = ALIGN(16);
__bss_end = .;
_end = .;__end = .; end = .;
PROVIDE (end = .);
BSS段开始了。
COMMON 这个保留字的意义:
通用符号(common symbol)的输入section:
在许多目标文件格式中,通用符号并没有占用一个section。连接器认为:输入文件的所有通用符号在名为COMMON的section内。
上例中将所有输入文件的所有通用符号放入输出.bss section内。
这里,定义了几个重要的符号
__bss_start = .;
__bss_end = .;
_end = .;
__end = .;
end = .;
在代码中可能会用到的。
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.debug 0 : { *(.debug) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : {*(.debug_pubnames) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.line 0 : { *(.line) }
.gptab.sdata : {*(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : {*(.gptab.bss) *(.gptab.sbss) }
}
余下的这几个意义也类似,看英文注释应该能明白。
对初步编译出来的一个二进制文件进行 nm 解析,得到如下内容
80100200 D __CTOR_END__
801001f8 D __CTOR_LIST__
80100208 D __DTOR_END__
80100200 D __DTOR_LIST__
80100220 A __bss_end
80100208 A __bss_start
80100220 A __end
80100208 A _edata
80100220 A _end
801001f8 A _etext
80100208 A _fbss
80100200 A _fdata
80100000 T _ftext
80108200 A _gp
80100000 T _start
80100038 t cleanpipe
80100220 A end
80100210 b flag_initialized.1263
80100158 T inbFrCom
801000b4 T initBss
80100060 T initConstructor
80100100 T initMips
801001a4 T outbToCom
80100140 T readComReg
801000f8 T showVersion
800fc000 T stack
80100000 T start
80100120 T writeComReg
可以看到,所有的地址全是从 0x80100000 开始的。
三个起始符号(T表示在text段中)
80100000 T _start
80100000 T start
80100000 T _ftext
几个函数都在代码段内
80100038 t cleanpipe
80100060 T initConstructor
801000b4 T initBss
801000f8 T showVersion
80100100 T initMips
80100120 T writeComReg
80100140 T readComReg
80100158 T inbFrCom
801001a4 T outbToCom
栈底地址果然是在 start 下方 0x4000 处
800fc000 T stack
(A 表示绝对不变)
801001f8 A _etext
80100200 A _fdata
80100208 A _edata
80100208 A _fbss
80100208 A __bss_start
80100220 A __bss_end
80100220 A __end
80100220 A _end
80100220 A end
全局构造和析构变量段(D表示在已初始化过的数据段中)
801001f8 D __CTOR_LIST__
80100200 D __CTOR_END__
80100200 D __DTOR_LIST__
80100208 D __DTOR_END__
还有一个是用 B 标记的,表示在未初始化的数据段中
80100210 b flag_initialized.1263
对应的代码是
static int flag_initialized = 0;
可以看出,这是个局部静态变量。
令其按地址排序
nm -n bamboo
800fc000 T stack
80100000 T _ftext
80100000 T _start
80100000 T start
80100038 t cleanpipe
80100060 T initConstructor
801000b4 T initBss
801000f8 T showVersion
80100100 T initMips
80100120 T writeComReg
80100140 T readComReg
80100158 T inbFrCom
801001a4 T outbToCom
801001f8 D __CTOR_LIST__
801001f8 A _etext
80100200 D __CTOR_END__
80100200 D __DTOR_LIST__
80100200 A _fdata
80100208 D __DTOR_END__
80100208 A __bss_start
80100208 A _edata
80100208 A _fbss
80100210 b flag_initialized.1263
80100220 A __bss_end
80100220 A __end
80100220 A _end
80100220 A end
80108200 A _gp
结合这些数据,去理解前面的 ld.script 的讲解,会有一个清晰的印象
相关推荐
mips-sde-elf-i686-pc-linux-gnu.tar.bz2
mips-sde-elf-i686-pc-linux-gnu.tar.bz2 下载这里来编译mips
MIPS ld脚本的见解
Mips的ld脚本会随着Ecos的编译进行。OUTPUT_FORMAT("elf32-bigmips", "elf32-tradbigmips", "elf32-tradlittlemips")OUTPUT_ARCH(mips:isa32)STARTUP(vectors.o)ENTRY(reset_vector) 启动到reset_vector段执行
x86架构Linux下的MIPS交叉编译工具链 mips-mti-elf-*
Codescape.GNU.Tools.Package.2017.10-05.for.MIPS.MTI.Bare.Metal.CentOS-5.x86_64
u-boot.lds分析
u-boot.lds代码如下: 简要说明该文件作用,该文件是链接脚本文件,在编译uboot时指定uboot可执行镜像文件链接方式,指定个段的装载地址与执行地址 /* /*指定输出文件格式elf,32位mips指令,大端*/ OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips") */ OUTPU
链接脚本详解
非常详尽的链接脚本语法讲解,学习脚本的好文档。
解码运动想象:BCI Competition IV 2a数据集实战指南
本文提供了BCI Competition IV 2a数据集的实战指南,详细解析了该经典运动想象脑电数据集的结构、文件格式与实验范式。通过MNE-Python等工具,逐步演示了从原始信号读取、预处理(通道选择、滤波、分段)到特征提取(CSP、频带功率)和模型训练(LDA、SVM)的完整流程,并强调了受试者独立评估的重要性,为BCI研究者提供了可复现的入门与进阶路径。
linux二进制反编译,mips 纯二进制反汇编(bin文件)
Usage: mipsel-linux-objdump Display information from object .At least one of the following switches must be given:-a, --archive-headers Display archive header information-f, --file-headers Display the...
PPPoE上网配置不求人:华为路由器命令行操作指南(2023最新版)
本文提供2023年最新的华为路由器PPPoE上网配置命令行操作指南。通过详细的步骤讲解,从连接设备、创建拨号接口、绑定PPPoE客户端到配置内网与NAT,手把手教你完成配置,并附有验证排错方法,助你轻松实现稳定上网。
链接文件的编写语法
您可以使用任何C赋值运算符创建全局符号,并为全局符号赋值(地址):在ld表达式中,赋值和其他运算符有两个区别。赋值只能在表达式的根处使用a=b+3;'是允许的,但a+b=3;'是一个错误。必须在赋值语句的末尾加一个尾随分号(“;”)。分配语句可能出现:作为ld脚本中的命令;或作为SECTIONS命令中的独立语句;或作为SECTIONS命令中节定义内容的一部分。前两种情况实际上是等效的——都定义了一个具有绝对地址的符号。
PMD相位偏折术实战:如何用Python处理条纹图,让金属外壳的划痕无处遁形
本文详细介绍了PMD相位偏折术在金属外壳划痕检测中的应用,通过Python实现条纹图处理和局部特征增强技术,显著提升微小缺陷的检出率。文章涵盖从四步相移条纹图采集到形状图局部增强的完整流程,特别适合工业质检场景,帮助实现高精度、高效率的自动化检测。
(3dnr)多帧视频图像去噪 (一)
视频图像去噪主要利用相邻帧间内容相似性,通过时域帧平均降低随机噪声。为避免运动物体产生"拖尾"现象,可采用运动自适应或运动补偿时域滤波方法。前者根据运动强度动态调整滤波系数,后者通过运动补偿使参考帧更接近当前帧。运动补偿方法虽能更好处理运动区域,但计算复杂度高且对快速运动场景效果有限。相比之下,运动自适应方法在实时视频处理中更具优势,能平衡去噪效果与硬件资源消耗。两种方法可根据场景动态切换以获得最佳去噪效果。
链接脚本基本语法
本文绝大部分翻译自https://users.informatik.haw-hamburg.de/~krabat/FH-Labor/gnupro/5_GNUPro_Utilities/c_Using_LD/ldLinker_scripts.html 最后一小部分翻译自:Builtin Functions (LD) 加上了一些我自己的备注。 链接脚本控制每次链接。这样的脚本是用链接器命令语言编写的。链接脚本的主要目的是描述如何将输入文件中的各个section(节)映射到输出文件中,并控制输出文件的内存布
用 CDS 作为 Referenced Data Source 开发 SAP Gateway OData 服务,一条更轻的 SEGW 路线
本文介绍了SAP Gateway项目中从传统手工建模到基于CDS View的现代化开发方式转变。主要内容包括: 传统方式需要在SEGW中手动创建Entity Type、Entity Set等元素,并在DPC_EXT中编写大量查询逻辑,存在模型层和业务逻辑重复表达的问题。 7.50版本后,SAP Gateway与ABAP CDS深度集成,可通过SEGW直接引用CDS View作为数据源,自动生成数据模型和SADL读取逻辑,支持完整的OData查询功能。 最佳实践建议通过Consumption View而非直接
LD 文件:规则详解
Contents 概论 基本概念 脚本格式 简单例子 简单脚本命令 对符号的赋值 SECTIONS命令 MEMORY命令 PHDRS命令 VERSION命令 脚本内的表达式 暗含的连接脚本 概论 每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制. 链接脚本主要用于规定如何把输入文件内的section...
微信小程序:使用mqtt手机屏幕锁屏后导致中断问题,让mqtt在手机黑屏后依然能保持连接及持续后台运行接收或处理任务,详解微信小程序MQTT在应用退到后台或手机熄屏的情况下自动检测并重连【强制保活】
微信小程序切后台后MQTT连接无法维持,微信小程序MQTT一旦用户锁屏、切换到后台或手机熄屏,连接就会断开,导致无法继续监听和处理业务消息,微信小程序mqtt保活方案,微信小程序屏幕锁屏或息屏导致mqtt连接中断怎么办,如何解决MQTT不能黑屏持续连接的问题,微信小程序应用退到后台 MQTT连接断开问题解决,苹果ios手机,安卓手机,uniapp微信小程序mqtt断开怎么解决,后台应用怎么保活,uni-app中MQTT连接频繁断开如何解决?应用退到后台后MQTT连接断开以及常连接断连的问题,微信小程序、MQ
计算机网络实验报告实验七可靠传输TCP协议分析
计算机网络实验报告实验七可靠传输TCP协议分析
LD文件详解
DEFINED(__heap_size__) 检查__heap_size__是否已经被定义,如果有定义就返回1,没定义就返回0。但是这里后面跟着?意义就变了,变成了像C语言一样“DEFINED(__heap_size__)?__heap_size__ : 0x00000400”成了一个整体。如果__heap_size__有定义就返回__heap_size__的值,没定义就返回0x00000400。
微信小程序 - 最新详细实现跳转打开第三方网站方法流程及示例代码,在小程序内直接打开H5页面或微信公众号文章后台业务域名配置及下载校验文件上传服务器,嵌入外部网站跳转第三方h5网页(详细配置及代码)
微信小程序,打开第三方网站,放校验文件,怎么配置业务域名,后台配置,怎么打开外部没有关联的网站,小程序直接打开公众号文章,指定页面,跳转第三方url,跳转到外部网站,小程序跳转到任意外部网页,网站链接,跳转到其他网页(外部链接),小程序嵌入外部h5链接,校验文件怎么放到对方服务器上,要跳转到网站没权限放过去,校验文件验证域名,把校验文件放到对面网站,别人的服务器也打不开没权限怎么放呢,勾选不校验合法域名,txt,打不开别人的网页怎么办,真机调试打不开,无法跳转,有什么其他办法不放校验文件吗,别人不可能同意,
ld、ld.so命令和ld.so.conf配置文件
ld.so.conf配置文件 动态装载器(dynamic loader) 程序如何进行动态链接呢?在/etc/ld.so.conf文件中存放着需要动态加载的目录,使用ldconfig就可以将ld.so.conf中的指定目录的库文件加载到内存中,并记录/etc/ld.so.cache中。ld.so.1文件就可以在高速缓存中训中动态库文件,提高访问速度。 例子: 在ld.so.conf文件中包含ld...
霍尼韦尔SoftMaster使用说明
霍尼韦尔SoftMaster使用说明
VB摄像头监控
该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制
链接脚本 ld文件 和 sct 文件的介绍
ld文件(GNU 链接器脚本)和sct文件(ARM 分散加载描述文件)都是用来的关键配置文件。
数学建模模型总结
这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!
嵌入式C语言--LD文件的概念
LD组合了许多对象文件和归档文件,重新定位它们的数据并绑定符号引用。通常编译程序的最后一步是运行LD。LD(Linker)文件是一个负责将目标文件和库文件链接成可执行文件或共享库的程序。每个可加载或可分配的输出section都有两个地址。第一个是VMA,即虚拟内存地址。这是运行输出文件时该节所拥有的地址。第二个是LMA,即加载内存地址。在大多数情况下,这两个地址将是相同的。
锂电池充电器电路设计 里面有电路
锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。
S32DS中.ld(链接)文件学习
程序代码(.s 和 .c)源文件会经过预编译、编译、汇编、链接最后生成目标可执行文件,.ld文件是作用在链接过程。链接的作用是:合并各个.obj文件的section,合并符号表,进行符号解析;符号地址重定位;生成可执行文件。linker_flash.ld:Flash和SRAM内存分配,为Flash构建目标分配代码段和数据段;linker_ram.ld:SRAM内存分配,为RAM构建目标分配代码段和数据段。可以利用.ld文件将函数和变量放置到自定义的地址中。ENTRY命令:运行一个程序时第一个被执行到的指令的
assert ld文件_LD 文件:规则详解
LD 文件:规则详解概论基本概念脚本格式简单例子简单脚本命令对符号的赋值SECTIONS命令MEMORY命令PHDRS命令VERSION命令脚本内的表达式暗含的连接脚本1. 概论每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名) 控制. 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局. 但你也...
【FreeRTOS】ld链接文件
本文介绍了STM32F407vg芯片的链接文件组成与功能,通过精确的内存规划和段管理,确保程序正确初始化和高效。
使用 ld 命令链接目标文件生成可执行文件
使用ld链接目标文件生成可执行文件,用于取代命令g++,仅仅用于学习ld命令的使用,不用于实际的项目编译。 首先看一个简单的C++源文件main.cpp。 // //@file:main.cpp // #include <iostream> using namespace std; int main() { cout<&l
2134



被折叠的 条评论
为什么被折叠?



