linker.ld在链接阶段的行为

抽出编译AM程序中的“打包用户程序am-test到ELF”步骤,看看链接脚本abstract-machine/scripts/linker.ld如何将库函数和用户程序链接起来的。

首先看下链接命令:

echo + LD "->" build/amtest-riscv32-nemu.elf
($CROSS_COMPILE)ld -z noexecstack -melf64lriscv
-T /abstract-machine/scripts/linker.ld--defsym=_pmem_start=0x80000000--defsym=_entry_offset=0x0--gc-sections-e _start-melf32lriscv
-o $AM_TEST/build/amtest-riscv32-nemu.elf--start-group$AM_TEST/build/riscv32-nemu/src/main.o$AM_TEST/build/riscv32-nemu/src/tests/video.o$AM_TEST/build/riscv32-nemu/src/tests/mp.o$AM_TEST/build/riscv32-nemu/src/tests/hello.o$AM_TEST/build/riscv32-nemu/src/tests/devscan.o$AM_TEST/build/riscv32-nemu/src/tests/audio/audio-data.o$AM_TEST/build/riscv32-nemu/src/tests/audio.o$AM_TEST/build/riscv32-nemu/src/tests/keyboard.o$AM_TEST/build/riscv32-nemu/src/tests/intr.o$AM_TEST/build/riscv32-nemu/src/tests/rtc.o$AM_TEST/build/riscv32-nemu/src/tests/vm.o/abstract-machine/am/build/am-riscv32-nemu.a/abstract-machine/klib/build/klib-riscv32-nemu.a--end-group

这里蕴含几个关键信息:

  • linker.ld作为链接的自定义脚本
  • 设置符号(symbol)_pmem_start的值为0x80000000,_entry_offset为0。
  • 设置程序的入口地址为_start

接下来我们转移到链接脚本abstract-machine/scripts/linker.ld的具体实现:

ENTRY(_start)
PHDRS { text PT_LOAD; data PT_LOAD; }SECTIONS {/* _pmem_start and _entry_offset are defined in LDFLAGS */. = _pmem_start + _entry_offset;.text : {		*(entry)	/* 引用与符号 entry 相关的所有内容*/*(.text*)	/* 将所有文件的 .text 段的内容合并到当前段*/} : text		/* 指定 .text 段被加载到名为 text 的内存区域中*/etext = .;_etext = .;.rodata : {*(.rodata*)}.data : {*(.data)} : dataedata = .;_data = .;.bss : {_bss_start = .;*(.bss*)*(.sbss*)*(.scommon)}_stack_top = ALIGN(0x1000);. = _stack_top + 0x8000;_stack_pointer = .;end = .;_end = .;_heap_start = ALIGN(0x1000);
}

linker.ld的链接内容:

  • 设置_start作为程序的入口点:ENTRY(_start)

  • 加载.text.data 段到内存中:PHDRS { text PT_LOAD; data PT_LOAD; }PT_LOAD是Program Header的类型

  • 设置当前地址_pmem_start + _entry_offset. 表示当前地址,_pmem_start + _entry_offset 就是定义当前地址的位置。这里的地址就是0x80000000

  • 设置.text.rodata.data.bss段。其中拿出.text段的处理

      .text : {		*(entry)	/* 引用与符号 entry 相关的所有内容*/*(.text*)	/* 将所有文件的 .text 段的内容合并到当前段*/} : text		/* 指定 .text 段被加载到名为 text 的内存区域中*/
    
  • 设置栈和堆的布局

    • _stack_top = ALIGN(0x1000); 确保栈从 4KB 对齐的位置开始。
    • . = _stack_top + 0x8000; 设置栈的初始位置,分配了 32KB 的栈空间。
    • stack_pointer = .; 设置 _stack_pointer 符号,指示栈指针的位置
  • 设置结束符号:end_end

  • 设置堆的起始地址,并确保堆从 4KB 对齐的位置开始 _heap_start = ALIGN(0x1000)

而其中符号entry是在abstract-machine/am/src/riscv/nemu/start.S中定义的

.section entry, "ax"
.globl _start
.type _start, @function_start:mv s0, zero				# 清零s0寄存器la sp, _stack_pointer		# 将标签 _stack_pointer 的地址加载到栈指针 sp 中,符号在linker.ld中定义。jal _trm_init				# 这条指令会跳转到 _trm_init 标签,并将当前指令地址(即 jal 的下一条指令的地址)压入栈中# _trm_init就是trm初始化函数

此程序设置了程序的入口点_start,并且将符号 _start 声明为一个函数类型。

至此,linker.d的行为就分析完了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834143.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js原型链污染

js原型链污染 原理介绍 对于语句:object[a][b] = value 如果可以控制a、b、value的值,将a设置为__proto__,我们就可以给object对象的原型设置一个b属性,值为value。这样所有继承object对象原型的实例对象在本身不拥有b属性的情况下,都会拥有b属性,且值为value。 可以通过…

基于米尔NXP i.MX93开发板OpenCV的相机捕捉视频进行人脸检测

本篇测评由优秀测评者“eefocus_3914144”提供。 本文将介绍基于米尔电子MYD-LMX93开发板(米尔基于NXP i.MX93开发板)的基于OpenCV的人脸检测方案测试。 OpenCV提供了一个非常简单的接口,用于相机捕捉一个视频(我用的电脑内置摄像头)1、安装python3-opencvapt install pyth…

hbase-2.2.7分布式搭建文档(附详细操作步骤命令及相关操作截图)

hbase-2.2.7分布式搭建文档 一,搭建前准备 1.检查是否已经安装JDK 2.搭建hbase前需要先搭建好hadoop 3.检查zookeeper是否正常启动 #启动zookeeper(三台都要启动) zkServer.sh start#查看zookeeper状态(一个leader两个follower) zkServer.sh status4.到官网或国内镜像站下载hb…

自动化构建镜像:Packer

在介绍Packer之前,先来回顾一下未使用Packer时自定义虚拟机镜像的步骤。先在本地启动一个虚拟机,从安装系统开始,再进行自定义配置或应用安装,最后封装压缩成镜像,详细操作步骤可以参考我之前写的文档,制作Centos 7镜像:https://robin-2016.github.io/2019/04/08/制作op…

牛逼!字节 IDE 来了!!

前言 大家好,我是R哥。 最近做面试辅导,很多同学和我抱怨说,去 XX 公司面试,刚进公司,面试官还没有见着呢,就让我先手撕两道算法题,做不出来的话直接 GG。 没错,如果你想拿一份还不错的收入,想去中大厂,特别是字节、阿里、腾讯这些一线大厂,面试前都会有一次算法笔试…

虚拟串口工具和串口调试工具详解 - 附下载地址

简介 串口开发过程中, 一般需要以下工具用于开发和调试:虚拟串口工具简介 虚拟串口软件, 可以在系统中虚拟出串口, 这样开发人员可以在没有物理串口设备的情况下进行开发. 串口调试工具简介 串口调试工具主要用于给串口发送信息, 测试串口是否连通, 发送消息是否正常被接收等.本…

怎么用云游戏玩Steam?ToDesk云电脑新手入门教程

对于新手玩家来说,想要上手Steam游戏,这门槛真有点高。不说要从众多真假难辨的软件中找出正版,遇到Steam内想玩的游戏还得等着下载安装解压,费时又费力。玩家想解决这个困难也很简单,只需下个ToDesk云游戏即可。它是ToDesk云电脑中专门玩游戏的版块,预安装了上百款热门游…

Vuex与Redux比较

由于Vuex和Redux都是从Flux中衍生出来,同时Vuex对Redux部分思想也有一些借鉴,所以Vuex和Redux有很多相同点。很多资料也有介绍两者的对比,但大部分讲解的比较抽象,较难理解。笔者整理两者异同点,同时配有标准案例进行说明。注意本文不是科普vuex和redux相关概念,相关知识…

第6篇 Scrum 冲刺博客

作业要求这个作业属于哪个课程 计科34班这个作业的要求在哪里 团队作业4——项目冲刺这个作业的目标 1.站立式会议2.发布项目燃尽图3.每人的代码/文档签入记录4.适当的项目程序/模块的最新(运行)截图5.每日每人总结会议照片昨日已完成的工作/今天计划完成的工作成员 昨天已完…

RabbitMQ 五种模式

RabbitMQ是一种常用的消息队列服务,它提供了五种消息模型:简单模型、工作队列模型、发布/订阅模型、路由模型、主题模型。1. 简单模型(Simple Message Queue,简称SQS):一个生产者,一个消费者,一个队列。 2. 工作队列模型(Work Queue):多个消费者共同处理一个队列中的…

如何防止手机被远程控制,安全远控推荐ToDesk

随着电子设备及各样应用的兴起,手机可以为人们带来的便利已越来越多,从二十年前的联络通话,到现如今的社交娱乐、导航、缴费等;通过智能手机中的软件均可轻松实现。 然而虽然手机的妙用有很多,但对于一些不太善用电子设备的中老年亲友来说,在使用中却也存在一定的被诈骗风…

Docker不再神秘 ------Ubuntu20.04 安装Docker 及实用技巧,建议收藏

Dockerdocker是一种容器,简而言之就是别人把一堆环境配置好了,你可以下载下来直接拿来使用(我的个人理解),有点像虚拟机你知道吧。比如下面这样,我直接打开了一个小电脑(docker),里面桌面啊、root啊全都有,跟你ubuntu系统类似,单说细节还不完全一样,毕竟它轻便哈哈…