【Golang源码分析】Golang如何实现自举 - 6l的链接过程(四)

2024-03-19 17:30

本文主要是介绍【Golang源码分析】Golang如何实现自举 - 6l的链接过程(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  接到催更的信息,其实还是很高兴。本来忙了很长一段时间为生活奔波,想给自己一个假期。后来脑子里响起了莎士比亚的一句话“如果一年到头如假日,岂不像连日工作那样疲乏?”,然后还是决定放下安逸的生活,继续去探索。

  经过最近一段时间的忙碌,对生活也多了一些重新的认识。人活着不要盲目,不要止步不前,不要高估自己的实力,也不要低估自己的能力,多一些自我审视,反复review或许在生活上、工作上走的会更远~

  一顿感概之后还是要回归主题,上一篇文章说到了go1.3编译使用了6g进行编译,编译成对应.a链接库。那么这一章接着来讲6l,那么继续来讲一下6l的实现过程与原理。

1.可执行文件介绍

  在链接的过程中就是为了生成可执行文件,那么可执行文件肯定需要固定的格式。在计算机科学中,不同系统的二进制文件,可执行文件,目标代码、共享库等格式是不同的。
  那么简单来介绍集中可执行文件的格式。

1.1 PE文件格式

  PE文件格式主要应用与Windows系列系统,可执行文件索引。说到pe格式有一个比较知名的黑客社区(看雪),就叫pediy。

  PE(Portable Executable)格式,是微软Win32环境可移植可执行文件(如exe、dll、vxd、sys和vdm等)的标准文件格式。PE格式衍生于早期建立在VAX®VMS®上的COFF(Common Object File Format)文件格式。PE结构如图1-1所示。

11.png

图1-1 PE格式

1.2 ELF文件格式

  ELF文件格式是linux系列系统,可执行文件索引;ELF格式如图1-2所示。

  ELF是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件标准格式,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。
12.png

图1-2 ELF格式

1.3 mach-o文件格式

  mach-o是mac系列系统的可执行文件格式,苹果系统是基于FreeBSD的,属于unix-like操作系统;

  Mach-O曾经为大部分基于Mach核心的操作系统所使用。NeXTSTEP,Darwin和Mac OS X等系统使用这种格式作为其原生可执行文件,库和目标代码的格式。而同样使用GNU Mach作为其微内核的GNU Hurd系统则使用ELF而非Mach-O作为其标准的二进制文件格式。

1.4 小节提醒

   其实文件格式在很多场景都会利用到,比如说经常听到的蠕虫病毒,还有外挂编程,还有软件查杀等等都会利用到。简单说,就拿PE结构来说,比如通过PE知道程序入口点,其实入口点一般都是代码段。那么在入口点动态注入代码,这样注入的代码段能做到复制,这就是一个蠕虫病毒的原理。

   当然除了这些以外什么对程序加壳,加密,加花都会涉及到文件格式。

   这边有一篇介绍文件结构比较好的文章:
https://blog.csdn.net/abc_12366/article/details/88205670

2.Inferno介绍

  6l除了使用plan9之外还使用了Inferno系统库。

  Inferno 是一个分布式操作系统,最初由贝尔实验室开发,但现在由 Vita Nuova 作为自由软件开发和维护。使用 Inferno 的并发编程语言 Limbo 编写的应用程序被编译为其可移植虚拟机代码 (Dis),以便在 Inferno 提供的可移植环境中的网络上的任何位置运行。不同寻常的是,该环境的外观和行为就像一个完整的操作系统。

  Inferno 以类似文件的名称层次结构表示服务和资源。程序仅使用文件操作打开、读/写和关闭来访问它们。“文件”不仅仅是存储的数据,还代表设备、网络和协议接口、动态数据源和服务。该方法统一并为所有系统资源提供基本的命名、结构和访问控制机制。单一的文件服务协议(与 Plan 9 的 9P 相同)使所有这些资源都可以通过网络以统一的方式导入或导出,与位置无关。应用程序只是将它需要的资源附加到它自己的每个进程名称层次结构(“命名空间”)。

  Inferno 可以在各种 ARM、PowerPC、SPARC 和 x86 平台上“本机”运行,也可以在现有操作系统(包括 AIX、FreeBSD、IRIX、Linux、MacOS X、Plan 9 和 Solaris)下“托管”,再次在各种平台上运行处理器类型。

  这个 Bitbucket 项目包括基本应用程序的源代码、Inferno 本身(托管和本机)、所有支持软件,包括本机编译器套件、基本可执行文件和支持文件。

Inferno源代码: https://bitbucket.org/inferno-os/inferno-os/

Inferno文档: http://www.vitanuova.com/inferno/

3.6l执行过程

  6l相对于6g来说会简单一些,6l其实就是针对不同的系统生成不同的执行文件结构,并且对文件结构填充数据。

3.1 调试内容

  想要了解6l的一些过程可以通过如下命令:

#/mnt/pkg/tool/linux_amd64/6g -o ./command-line-arguments.a   -D _/mnt/src/demo  -pack ./demo.go#/mnt/pkg/tool/linux_amd64/6l -v -o demo -extld=gcc ./command-line-arguments.a

   如上命令其实做了两件事情,一个是通过6g生成.a库,另外一个是通过6l链接6g生成的库。

  既然知道6l命令用途,那么下断点的话,肯定要对6l进行调试,命令如下:

#gdb /mnt/pkg/tool/linux_amd64/6l

  进入gdb模式后,需要设置编译参数,参数如下:

(gdb) set args -v -o demo -extld=gcc ./command-line-arguments.a

  设置完参数后,就可以“b mian”下断点了,比较简单,就不赘述了。

3.2 过程介绍

  经过对源码的阅读后,整理了一张流程图,如图3-1所示。
31.png

图3-1 6l链接过程

  根据上图可以得知plan9作为一个操作系统库,可以执行不同程序的main函数。除此之外在链接过程中会做一些操作,比如创建输出文件。根据不同的系统通过headtype函数获得不同的文件格式类型,如图3-2所示。
32.png
图3-2 不同系统的文件格式

  通过文件格式类型调用archinit生成不同的可执行结构,不同的结构对应一套代码,对应的dwarf结构、elf结构、mach-o结构、pe结构,如图3-3所示。
33.png
图3-3 不同系统的文件格式

  然后会调用各种函数对可执行结构进行数据段,代码段,系统描述符表,链接库等做数据填充,最后刷新到输出文件。

总结

  
  了解6l之后对跨平台和可移植性系统有了一些认识,并且掌握了如下知识:

  • 不同系统之间存在不同的可执行文件结构。
  • 6l除了使用plan9之外还使用了Inferno系统库。
  • plan9作为一个操作系统库,可以执行不同程序的main函数。
  • headtype函数与archinit函数组合使用,针对不同的系统,初始化不同的结构体。
  • 链接过程其实是通过可执行文件结构体填充不同程序段的数据。

  其实针对填充的数据里还有很多更细节的,比如导出表,导入表等等。如果有兴趣可以自行研究,除此之外还有可执行程序的执行原理,比如unix/linux的execvp、windows的CreateProcessW等内核态调用细节。

这篇关于【Golang源码分析】Golang如何实现自举 - 6l的链接过程(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826746

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问