libc如何工作?

Tam*_*lei 2 c c++ emulation libc mips32

我正在编写一个MIPS32仿真器,并希望在使用gcc编译C程序时可以使用整个标准C库(可能使用GNU扩展).

据我所知,I/O由MIPS32架构上的系统调用处理.要使用libc/glibc成功运行程序,如何判断我需要模拟哪些系统调用?(没有反复试验)

编辑:请参阅示例,了解syscalls的含义.

(如果您有兴趣,可以在这里查看项目,欢迎任何反馈.请记住,它处于非常早期的阶段)

Blr*_*rfl 6

非常简短的答案

阅读更长的答案.

简答

如果您打算提供一个自定义libc,它使用模拟器的某些功能让主机操作系统执行系统调用,则必须实现所有这些功能.

更长的答案

退一步,看看事物通常在真实(非模拟)系统中分层的方式:

  1. 外围设备有一些I/O接口(例如,编号端口或内存映射),CPU可以发痒,使他们做任何事情.
  2. CPU运行的软件了解如何操作硬件.这可以是单用途程序或运行其他程序的操作系统.由于libc在图片中,让我们假设有一个操作系统,它就是Unix-y.
  3. OS运行的用户空间程序使用它们自己和OS之间的定义接口来要求执行某些"系统"功能.

您要完成的任务发生在第3层和第2层之间,其中libc或用户代码中的函数执行OS定义为触发系统调用的任何内容.这开辟了无数的蠕虫:

  • 操作系统定义为触发系统调用的内容因操作系统而异,并且(很少)在同一操作系统的版本之间.通过提供可动态链接的libc来处理隐藏这些细节,可以在"真实"系统上减轻这个问题.除此之外,如果您要运行MIPS32二进制文件,它是否使用您的模拟器支持的系统调用约定?

  • 您需要提供一个自定义libc,它可以让您的模拟器识别为进行特定系统调用并执行它.您希望运行的任何程序都必须交叉编译到MIPS32并与其静态链接,程序需要的任何其他库(libm都会想到)也是如此.或者,您的模拟器包需要提供动态链接器的模拟以及所有必需库的动态链接副本,因为在主机上打开它们将不起作用.如果您有足够的源代码从头开始重新编译程序,移植可能比模拟更好.

  • 任何对特定系统上的文件路径进行假设的代码,或者对某些设备(它们本身是文件)中的内容的其他假设都不能正确运行.

  • 如果您要提供第2层,那么您需要对自己进行签名,以便对整个操作系统的某个特定版本的行为进行完整,正确的模拟.有些电话喜欢read()并且write()很容易处理; 其他人喜欢fork(),uselib()而且ioctl()会困难得多.您的程序使用的调用和行为与主机操作系统提供的调用和行为之间也不一定是一对一的映射.所有这些假设主机是Unix,目标程序也是.如果针对某些其他环境编译目标,则所有投注均已关闭.

最后一点是大多数仿真器只提供CPU和某些目标系统的硬件行为(即第1层中的所有内容)的原因.有了这些,您可以运行原始系统的引导ROM,操作系统和用户程序,所有这些都不会改变.有许多现有的MIPS32仿真器可以执行此操作,并且可以运行在其仿真的硬件上运行的操作系统的未更改版本.

HTH,祝你的项目好运.