可变长数据

在整个DWARF中有大量信息使用整数值来表示,从数据段偏移量,到数组或结构体的大小,等等。由于大多数整数值是小整数,用几位就可以表示,因此这意味着数据主要由零组成,对应的bits相当于被浪费了。

DWARF定义了一个可变长度的整数编码方案,称为Little Endian Base 128(LEB128),它能够压缩实际占用的字节数,减小编码后的数据量。LEB128有两种变体:

  • ULEB128: 用于编码无符号整数
  • SLEB128: 用于编码有符号整数

ULEB128编码方案

UELB128编码算法:

MSB ------------------ LSB
      10011000011101100101  In raw binary
     010011000011101100101  Padded to a multiple of 7 bits
 0100110  0001110  1100101  Split into 7-bit groups
00100110 10001110 11100101  Add high 1 bits on all but last (most significant) group to form bytes
    0x26     0x8E     0xE5  In hexadecimal

→ 0xE5 0x8E 0x26            Output stream (LSB to MSB)

用咱家乡话总结下就是:

  1. 将数字转换为二进制数表示,这些字节按小端序排列(即最低有效字节在前)
  2. 将整数按7位一组进行分割
  3. 每组7位存储在一个字节中,该字节的最高位(第8位)用作标志位:
    • 如果后面还有更多组,则该位设为1
    • 如果是最后一组,则该位设为0

例如,数字Uint64 624485的ULEB128编码为:

624485 = 0x98765

十六进制数,一个数位由4位二进制表示,转换为二进制表示为:

1001 1000 0111 0110 0101

考虑到7位一组进行分割,先填充为7bits的整数倍:

0 1001 1000 0111 0110 0101

然后7位一组进行分割,注意是小端字节序,所以从右边开始分割:

0 1001 10 / 00 0111 0 / 110 0101
  • 第1组: 110 0101,因为后续还有,所以第8位标记为1,最终为 1110 0101 = 0xe5
  • 第2组: 00 0111 0, 000 1110,第8位标记为1,最终为 1000 1110 = 0x8e
  • 第3组: 0 1001 10, 010 0110,第8位标记wi0,最终为 0010 0110 = 0x26

编码后的字节序列为: []byte{0xe5 0x8e 0x26},最终只占用了3个字节,而如果用原始数据类型uint64则要用8个字节。

SLEB128编码方案

SLEB128的编码规则类似,只是在处理负数时需要考虑符号位扩展,处理正数时没有区别。

SLEB128负数编码算法:

MSB ------------------ LSB
         11110001001000000  Binary encoding of 123456
     000011110001001000000  As a 21-bit number
     111100001110110111111  Negating all bits (ones' complement)
     111100001110111000000  Adding one (two's complement)
 1111000  0111011  1000000  Split into 7-bit groups
01111000 10111011 11000000  Add high 1 bits on all but last (most significant) group to form bytes
    0x78     0xBB     0xC0  In hexadecimal

用咱家乡话说就是:

  1. 如果是负数,先转换为二进制补码表示
  2. 然后7bits一组进行分组,依然按照小端来
  3. 除了最后一组,每个分组的第8位都标记为1
  4. 得到最终结果

本文总结

本文介绍了ULEB128、SLEB128这种对小整数编码存储友好的编码方案,可以节省存储空间占用。对于正数,ULEB128、SLEB128编码结果是相同的,只是对于负数时,SLEB128要先转换为其补码再进行编码。通过这种编码方式,DWARF能够有效压缩整数数据,减小调试信息的体积。在实际应用中,大多数整数值都可以用1-2个字节表示,相比固定4字节或8字节的存储方式节省了大量空间。

results matching ""

    No results matching ""