前面的文章中提到了 .rdata 是用于保存常量数据的节,这里对这个位置进行研究。
首先从 \Build\AppPkg\DEBUG_VS2015x86\X64\AppPkg\Applications\Hello\Hello\OUTPUT\Hello.map 看到 Section 分布:
Start Length Name Class
0001:00000000 000012f7H .text$mn CODE
0002:00000000 000006f4H .rdata DATA
0002:000006f4 00000110H .rdata$zzzdbg DATA
0003:00000000 00000020H .data DATA
0003:00000020 00000020H .bss DATA
0004:00000000 000000a8H .pdata DATA
0005:00000000 00000084H .xdata DATA
对应的,在下面有这个段对应偏移的内容:

比如,其中有下面这样一条:
0002:00000690 mHexStr 0000000000001c50 BasePrintLib:PrintLibInternal.ob
我们查看 \MdePkg\Library\BasePrintLib\PrintLibInternal.c有如下定义:
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
对应代码:
/**
Internal function that convert a number to a string in Buffer.
Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
@param Buffer Location to place the ASCII string of Value.
@param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
@param Radix Radix of the value
@return A pointer to the end of buffer filled with ASCII string.
**/
CHAR8 *
BasePrintLibValueToString (
IN OUT CHAR8 *Buffer,
IN INT64 Value,
IN UINTN Radix
)
{
UINT32 Remainder;
//
// Loop to convert one digit at a time in reverse order
//
*Buffer = 0;
do {
Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);
*(++Buffer) = mHexStr[Remainder];
} while (Value != 0);
//
// Return pointer of the end of filled buffer.
//
return Buffer;
}
结合代码可以出这个是用来将十进制数值转化为十六进制字符串的,对于一般的打印处理是会用到的。
使用 CFF 打开 EFI 文件,查看 .rdata Section(红色框中),可以在其中看到定义的字符串:

如果把上面的 0x34修改为0x46,再次运行 Hello.efi 就会用不同的值显示出来。修改之前运行结果如下:

修改之后运行的结果:

因此,可以确定在 .rdata 中存放了mHexStr[]用于十进制对十六进制显示的转换。这就是 .rdata存放的常量的作用。