Page 27 - 《软件学报》2025年第12期
P. 27

5408                                                      软件学报  2025  年第  36  卷第  12  期


                    如图  4  所示, 在静态链接模式下, swLLVM      编译器采用!ldmhigh/!ldmlow  重定位对    LDM  变量进行相对偏移寻
                 址, 以规避基于全局偏移表        (global offset table, GOT) 间接寻址的!literal 重定位所引入的额外访存开销     [22] . 其中,
                 !literal 重定位需要  ldl 和  stw  两次访存, 而!ldmhigh/!ldmlow  重定位仅需要  stw  一次访存.


                                         #   !literal example  #   !ldmhigh/!ldmlow example
                                         ldi        $t1, 1($zero)  ldi        $t1, 1($zero)
                                         ldl        $t0, a($gp)     !literal  ldih      $t0, a($zero)     !ldmhigh
                                         stw       $t1, 0($t0)  stw      $t1, a($t0)         !ldmlow
                                         图 4 !literal 与!ldmhigh/!ldmlow  重定位的汇编示例

                    若动态链接模式继续沿用该实现方案, 那么每个动态库的.ldm                   段均从相同物理地址开始编址. 这种做法会引
                 发一个问题, 即不同动态库中的          LDM  变量可能产生地址冲突, 具体情形可参见图              5. 在该示例中, 由于    libB.so  中
                 的  Callee 函数可能会使用到    libA.so  中静态声明的  LDM  数组  a[64], LDM  变量地址冲突可能会导致程序运行结果
                 出现错误.

                                              Virtual addr space      Physical
                                          …                          addr space
                                                                    …
                                                 libA.so
                                          .ldm
                                            …                       …
                                            a[64]   #offset=0x20    0x20: …
                                            …                       …
                                                               Map  …
                                                                      Address
                                          …                      a  0x40: …
                                                                      conflict
                                                 libB.so            0x60: …   b
                                          .ldm                      …
                                            …                       0x80: …
                                                                    …
                                            b[64]   #offset=0x40
                                            …
                                          …                         …
                                         图 5 动态链接模式下       LDM  变量地址冲突的示例

                    为了有效满足      Julia 等动态应用对片上存储空间的访问需求, 并尽可能避免额外的性能开销, 我们在                      swLLVM
                 中设计并实现了一种针对动态链接模式的片上存储空间优化访问方法. 对于在动态库中静态声明的                                   LDM  变量,
                 swLLVM  编译器继续使用!ldmhigh/!ldmlow   重定位进行相对偏移寻址, 以确保片上存储空间的访问效率. 同时, 为
                 了让动态链接器能够准确识别和处理上述重定位, 我们在编译器和二进制工具链中新增了两种重定位类型
                 (R_SW_64_LDMHI 和  R_SW_64_LDMLO), 并且在构建动态库的重定位表时详细登记相关的重定位信息. 图                     6  清
                 晰地展示了图     5  中的  libA.so  动态库在实施上述访存优化后的重定位表内容.


                        $ readelf  -r libA.so
                        Relocation section '.rela.dyn' at offset 0x10ee8 contains 2 entries:
                           Offset        Info         Type            Sym. Value   Sym. Name + Addend
                        0000000014a8   00330000002a  R_SW_64_LDMHI  0000000010000000   a + 0
                        0000000014b0  00330000002b  R_SW_64_LDMLO  0000000010000000   a + 0
                        …
                                          图 6 LDM   访存优化后的动态库重定位表信息

                    在动态库的加载过程中, 动态链接器会执行!ldmhigh/!ldmlow            重定位的修正操作, 具体流程参见算法            1. 首先,
                 动态链接器利用操作系统提供的            mmap() 接口为当前动态库的.ldm      段分配物理地址, 记为       ldm_pstart. 然后, 动态
                 链接器遍历当前动态库的重定位表             relaTable, 特别关注  R_SW_64_LDMHI 和  R_SW_64_LDMLO  两类重定位信
                 息. 对于上述重定位对应的        LDM  变量, 根据其所在.ldm    段的起始物理地址      ldm_pstart 以及该变量在.ldm  段内的相
                 对偏移量   offset, 动态链接器能够精确计算出该变量的实际物理地址, 记为                 ldm_paddr. 最后, 针对不同的重定位类
                 型, 动态链接器根据      ldm_paddr 计算和修正相应汇编指令的偏移字段.
   22   23   24   25   26   27   28   29   30   31   32