Page 88 - 《软件学报》2025年第7期
P. 88

贾昂 等: 面向函数内联场景的二进制到源代码函数相似性检测方法                                                 3009



                         14 000
                                 O0
                                 O1
                         12 000  O2
                                 O3
                         10 000
                         函数调用的数量  8 000

                          6 000
                          4 000

                          2 000
                            0
                                O0O1O2O3O0O1O2O3O0O1O2O3O0O1O2O3O0O1O2O3O0O1O2O3O0O1O2O3O0O1O2O3
                                 GCC-4.9.4  GCC-5.5.0  GCC-6.4.0  GCC-7.3.0  Clang-4.0  Clang-5.0  Clang-6.0  Clang-7.0
                                             图 3 不同编译选项之间的函数内联关系

                 3.2.2    不同编译器下的函数内联关系
                    为了进一步分析不同编译器间函数内联的相关性, 本节使用公式                     (1) 计算它们之间的相似度:

                                                         opt
                                                        ∑
                                                           |ICS cp1 ∩ ICS cp2 |
                                                         i
                                              Sim cp1−cp2 =             ×2                            (1)
                                                        opt
                                                       ∑(              )
                                                          |ICS cp1 |+|ICS cp2 |
                                                        i
                    在公式   (1) 中,  ICS  代表被内联的函数调用,     cp1 和  cp2 分别代表两个要比较的编译器.        |ICS cp1 ∩ ICS cp2 | 表示



                 在相同优化级别下, 同时在        cp1 和  cp2 中被内联的函数调用数.      ICS cp1  和   ICS cp2  分别代表在  cp1 和  cp2 中被内联
                             opt
                             ∑(              )
                 的函数调用数.        |ICS cp1 |+|ICS cp2 |  意味着总结所有优化级别的比较结果.
                              i
                    图  4  中展示了  8  个编译器之间的相似结果, 其中颜色越深, 表示相似程度越高.

                                                                              1.00
                                         Clang-7.0
                                                                              0.95
                                         Clang-6.0
                                                                              0.90
                                         Clang-5.0
                                                                              0.85
                                         Clang-4.0
                                                                              0.80
                                         GCC-7.3.0
                                                                              0.75
                                         GCC-6.4.0
                                                                              0.70
                                         GCC-5.5.0
                                                                              0.65
                                         GCC-4.9.4
                                              GCC-4.9.4 GCC-5.5.0 GCC-6.4.0 GCC-7.3.0 Clang-4.0 Clang-5.0 Clang-6.0 Clang-7.0

                                             图 4 不同编译器之间的函数内联关系

                    如图  4  所示, 同一编译器家族的编译器做出类似的内联决策. 例如, GCC-4.9.4              和  GCC-5.5.0  中  95%  的内联函
                 数调用是一致的. 总体而言, GCC        编译器中    95.2%  函数调用的内联结果是一致的, 而在          Clang  编译器中  94.9%  函
                 数调用的内联结果是一致的.
                    尽管在同一编译器的不同优化级别以及同一家族的编译器间, 内联行为显示出明显的相关性, 但不同编译器
   83   84   85   86   87   88   89   90   91   92   93