Box86源码解读记录

news2025/1/12 10:41:53

1. 背景说明

Github地址:https://github.com/ptitSeb/box86

官方推荐的视频教程:Box86/Box64视频教程网盘

2. 程序执行主体图

Box86版本: Box86 with Dynarec v0.3.4

在这里插入图片描述
主函数会执行一大堆的初始化工作,包括但不限于:BOX上下文 、内存部局、空间分配、x86指令模拟器、ELF文件 、依赖库文件、所有准备工作完成之后,在x86模拟器中按着IP指针,开始顺序解释执行代码块

3. 代码说明-main函数

/src/main.c
因为main函数代码量比较大,下边是精简后的代码,省略了大部分非主干流程代码,这样看起来就容易很多了。

int main(int argc, const char **argv, char **env)
{
    init_malloc_hook();
    init_auxval(argc, argv, environ?environ:env);
   .........
    //创建一个Box86的上下文、这个上下文将会持有着,在转译时可能用到的全部信息
    my_context = NewBox86Context(argc - nextarg);

    //检查并读取必须用到的环境变量信息(例如:LD_LIBRARY_PATH、BOX86_EMULATED_LIBS、libssl.so、BOX86_PATH 等等)
    LoadEnvVars(my_context);
    .........
    //通过 ParseElfHeader 方法将当前要执行 ELF 文件的头信息解析出对应的 elfheader_t 结构 
    elfheader_t *elf_header = LoadAndCheckElfHeader(f, my_context->fullpath, 1);

    /* 将 ELF 头信息添加到当前Box86的上下文中
 CalcLoadAddr(elf_header); //这个函数的作用是根据 ELF 文头信息来计算或确定一些关键的内存布局参数。(包括虚拟地址(vaddr)、物理地址(paddr)、内存大小(memsz)、对齐(align)、栈大小(stacksz)、栈对齐(stackalign)、TLS(线程局部存储)等等)*/
    AddElfHeader(my_context, elf_header);

//根据 ELF 头部信息设置内存布局
    if(CalcLoadAddr(elf_header)) {
        printf_log(LOG_NONE, "Error: reading elf header of %s\n", my_context->fullpath);
        free_contextargv();
        FreeBox86Context(&my_context);
        FreeCollection(&ld_preload);
        FreeElfHeader(&elf_header);
        return -1;
    }
    
    //根据 ELF 头部信息和内存布局参数,来为 ELF 文件的加载分配内存。
    if(AllocLoadElfMemory(my_context, elf_header, 1)) {
        printf_log(LOG_NONE, "Error: loading elf %s\n", my_context->fullpath);
        free_contextargv();
        FreeBox86Context(&my_context);
        FreeCollection(&ld_preload);
        FreeElfHeader(&elf_header);
        return -1;
    }
    
    /*设置bss段空间以及未初始化的静态和全局变量空间
CalcStackSize(my_context); //计算栈空间大小以及内存对齐方式,初始值为8M空间、4Byte对齐,再根据context->elfs数组值来遍历,如果数组中有值大于初始值,则调整为数组中的最大值, 然后用 mmap 分配空间*/
    my_context->brk = ElfGetBrk(elf_header);
    .........
    
    //通过Box86的上下文配置,调用internalX86Setup创建了一个X86运行的模拟器
    x86emu_t *emu = NewX86Emu(my_context, my_context->ep, (uintptr_t)my_context->stack, my_context->stacksz, 0);
    // stack setup is much more complicated then just that!
    SetupInitialStack(emu); //设置x86模拟器初始栈
    SetupX86Emu(emu);

    //按照X86应用程序的逻辑main函数的加载过程一样 ,将应用程序的参数加到EAX和EBX,以此来模拟X86程序的启动
    SetEAX(emu, my_context->argc);
    SetEBX(emu, (uint32_t)my_context->argv);
    .........
    
    //负责解析ELF文件中的符号信息,并将它们分类到不同的符号表中,以便于后续的符号解析和链接使用
    AddSymbols(my_context->maplib, GetMapSymbols(elf_header), GetWeakSymbols(elf_header), GetLocalSymbols(elf_header), elf_header);
    .........
    
    //负责在加载主 ELF 文件时,将其信息添加到链接映射中,以便动态链接器可以正确地解析符号和执行重定位。
    AddMainElfToLinkmap(elf_header);
    .........
    //解析 ELF 文件的动态依赖,并加载相应的库
    if(LoadNeededLibs(elf_header, my_context->maplib, 0, 0, my_context, emu)) {
        printf_log(LOG_NONE, "Error: loading needed libs in elf %s\n", my_context->argv[0]);
        FreeBox86Context(&my_context);
        return -1;
    }
    .........
    //解释运行X86程序 
    DynaRun(emu);
    // Get EAX
    int ret = GetEAX(emu);
    .........
    return ret;
}

4. 代码说明-xxx函数

5. 代码说明-xxx函数

6. 代码说明-xxx函数

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三层交换机静态路由连通实验

静态路由是一种手动配置路由表的方式,网络管理员需要手动指定网络中的每一个路由器下一跳路由器的地址,以及到达目的网络的最短路径。静态路由的路由表不会自动更新,如果网络拓扑发生了变化,管理员需要手动更改路由表。 实验拓扑图…

信息系统架构模型_1.单机应用模式和客户机/服务器模式

1.单机应用模式(Standalone) 单机应用系统是最简单的软件结构,是指运行在一台物理机器上的独立应用程序。这些软件系统,从今天的软件架构上来讲,是很简单,是标准的单机系统。当然至今,这种复杂的…

面向对象 03:类与对象的创建、初始化和使用,通过 new 关键字调用构造方法,以及创建对象过程的内存分析

一、前言 记录时间 [2024-05-10] 系列文章简摘: Java 笔记 01:Java 概述,MarkDown 常用语法整理 Java 笔记 11:Java 方法相关内容,方法的设计原则,以及方法的定义和调用 面向对象 01:Java 面向对…

数学:人工智能领域的基石与灵魂

在科技日新月异的今天,人工智能(AI)已经渗透到了我们生活的方方面面,从智能家居、智能医疗到自动驾驶、智能客服,AI无处不在。然而,当我们赞叹于AI的神奇时,却往往忽视了其背后的推动力——数学…

Leetcode—2105. 给植物浇水 II【中等】

2024每日刷题&#xff08;131&#xff09; Leetcode—2105. 给植物浇水 II 实现代码 class Solution { public:int minimumRefill(vector<int>& plants, int capacityA, int capacityB) {int size plants.size();int i 0;int j size - 1;int capA capacityA;in…

结合创新!通道注意力+UNet,实现高精度分割

在U-Net网络中加入通道注意力机制能显著提升模型的性能&#xff01; 具体点说是在U-Net的卷积层之后添加一个通道注意力模块&#xff0c;这样这个模块可以学习不同通道之间的权重&#xff0c;并根据这些权重对通道进行加权&#xff0c;从而增强重要通道的特征表示。 这种结合…

【WebGIS实例】(14)MapboxGL 加载地形高程数据

前言 官网示例&#xff1a;Add 3D terrain to a map | Mapbox GL JS | Mapbox 大佬博客&#xff1a;Mapbox GL基础&#xff08;七&#xff09;&#xff1a;地形数据的处理与加载 (jl1mall.com) 加载Mapbox地形数据 map.once(style.load, () > {map.addSource(mapbox-dem,…

常见扩频系统的基础概念和模型

扩频系统是一种通信技术&#xff0c;它通过将信号的频谱扩展到一定程度来实现传输&#xff0c;这种系统的设计和实现涉及到多种不同的方法和技术。 扩频系统的主要特点和好处包括&#xff1a; 抗干扰能力强&#xff1a;由于信号被扩展到较宽的频带上&#xff0c;单位带宽内的功…

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水 503.下一个更大元素II 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元…

jenkins使用gitLab(极狐)认证登陆

jenkins安装 GitLab Authentication插件 我因为java版本和最新GitLab Authentication 1.19版本不兼容&#xff0c;选择了本地安装 找个历史版本1.13版本&#xff0c;然后下载到电脑上 - 本地上传插件并安装 在极狐上创建一个应用 - 配置应用信息 应用名&#xff1a;jenkinsLo…

GAMMA Lab——知识图谱和LLM大模型

图机器学习的发展与分类 图基础模型 LLM基础模型 GNN LLM 前沿工作

【Web后端】servlet基本概念

1.ServletAPI架构 HttpServlet继承GenericServletGenericServlet实现了Servlet接口&#xff0c;ServletConfig接口,Serializable接口自定义Servlet继承HttpServlet 2.Servlet生命周期 第一步&#xff1a;容器加载Servlet第二步&#xff1a;调用Servlet的无参构造方法&#xf…

Oracle -在线回缩表

conn scott/tiger DROP TABLE EMP1 PURGE; CREATE TABLE EMP1 AS SELECT * FROM EMP; alter table emp1 enable row movement; -- 启动回缩特性 insert into emp1 select * from emp1; / / commit; -- 增加到14000行 -- 分析表的结构 analyze table emp1 comput…

mysql从库SHOW SLAVE STATUS字段详解

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 mysql从库SHOW SLAVE STATUS字段详解 前言输出字段展示字段说明 前言 在数据库的舞台上&#xff0c;主从同步就像是一场华丽的舞蹈&#xff0c;而SHOW SLAVE STATUS命令则是这场舞蹈的灯光&#xff0…

Spark Streaming笔记总结(保姆级)

万字长文警告&#xff01;&#xff01;&#xff01; 目录 一、离线计算与流式计算 1.1 离线计算 1.1.1 离线计算的特点 1.1.2 离线计算的应用场景 1.1.3 离线计算代表技术 1.2 流式计算 1.2.1 流式计算的特点 1.2.2 流式计算的应用场景 1.2.3 流式计算的代表技术 二…

10个超实用的Excel技巧!207套Excel模板(电商、数据分析、排班表、工作计划表)

职场如战场&#xff0c;掌握Excel技能&#xff0c;让你的工作效率飙升&#xff01; 今天&#xff0c;我给大家分享10个Excel的超实用技巧&#xff0c;让你从Excel小白秒变大神&#xff01; 1️⃣ 快速求和&#xff1a;使用 Alt 一键求和&#xff0c;告别手动输入SUM函数。 …

【HMWeb】HTML使用Leaflet实现本地离线地图Gis应用

下载Leaflet 官网下载&#xff1a;https://leafletjs.com/reference.html CSDN&#xff1a;https://download.csdn.net/download/hmxm6/89291989 选择版本号 添加html文件 加入代码 <!DOCTYPE html> <html lang"en"> <head><meta charset&qu…

智慧公厕解决什么问题?实现了什么样的价值?

公共厕所一直是城市管理的难题&#xff0c;常常面临着卫生条件不佳、管理不善以及使用体验差等问题。为了解决这些困扰城市的难题&#xff0c;智慧公厕应运而生。智慧公厕不仅应用了信息化和数字化技术&#xff0c;还通过全方位的智能化应用&#xff0c;彻底改变了传统公厕的面…

(十)JSP教程——config对象

config对象是脚本程序配置对象&#xff0c;表示当前JSP页面的配置信息。由于JSP页面通常无需配置&#xff0c;因此该对象在JSP页面中比较少见。 config对象可以读取一些初始化参数的值&#xff0c;而这些参数一般在web.xml配置文件中可以看到&#xff0c;并通过config对象的相应…

Python写了for i in range(10)却只打印一遍?

题目&#xff1a;定义一个两个参数的重复打印函数&#xff0c;第一个参数指定要打印的字符串&#xff0c;第二个参数指定要重复打印的次数&#xff0c;在主程序中调用该函数&#xff0c;打印10遍你的学号姓名。 为什么调用函数后结果只打印了一遍? 看了题目感觉就很诡异&#…