如何在 CIL .data-declarations

问题描述

我正在编写一个针对通用中间语言的编译器,并希望对全局变量使用 .data 声明。我的意思是 Spec 的第 II.16.3.1 节。

如何使用被描述为“标签地址”的内容?以下确实使用 .NET-Core 的 ilasm 进行组装:

.assembly extern mscorlib
{
    .ver 4:0:0:0
}
.assembly 'string'
{
}
.module 'string'

.data hello_world_data = { int8(72),int8(101),int8(108),int8(111),int8(32),int8(87),int8(114),int8(100),int8(33),int8(0) }

.field static int8 hello_world at hello_world_data

.data addr_of_data = &(hello_world_data)

.field static int8* hello_world_ptr at addr_of_data

.method public static default int32 main () cil managed {
    .entrypoint

    ldc.i4.0
    ret
}

但是当我尝试执行上面的代码时,我收到以下错误消息(在 Linux 上使用 .NET-Core):

Unhandled exception. System.BadImageFormatException: Could not load file or assembly '/home/lou/uni/proj/stuff/tests/test-global-arrays/string.exe'. An attempt was made to load a program with an incorrect format.

File name: '/home/lou/uni/proj/stuff/tests/test-global-arrays/string.exe'


[1]    12019 abort (core dumped)  dotnet string.exe

有什么想法/帮助吗?

解决方法

如果这对您很重要,我建议您在 https://github.com/dotnet/runtime 存储库中提交问题。

我认为这在 Windows 之外不起作用的原因是这些指令生成带有重定位的数据(可执行文件中的位置,一旦可执行文件加载到内存中,就需要使用真实地址进行修复)。由于 .NET 中可执行文件的格式基于 Windows PE 格式,因此 Windows 在加载可执行文件时会处理重定位。

在 Windows 之外,CoreCLR 附带一个小的“Windows 加载程序模拟器”,它以 Windows 加载它们的方式加载 .NET 可执行文件。但它可能错过了这些重定位的处理。否则,IL 格式不会生成重定位。

但是这些重定位在很多地方都会有问题(我完全希望像 IL 链接器这样的工具会错过它们并损坏它们,我认为 Mono 也没有处理这些问题,它们将会有问题用于AOT编译等)。