文档
注册

生成BC文件

BC(BitCode)文件是使用LLVM(Low Level Virtual Machine)编译源代码生成中间文件(IR)的二进制表示,包含了程序编译的中间代码,比源代码文件更加紧凑和高效。DevKit基于LLVM框架,利用BC文件,提高程序的分析效率与分析准确度。

LLVM是一种开源编译器基础设施,它提供了一个通用的编译器框架和工具链,可以用于构建各种编程语言的编译器、解释器、调试器、代码优化器等。

  • 重构版本向量化检查中,使用工程构建工具生成BC文件时,不能指定CC、CXX、FC变量。

前提条件

用于生成BC文件的项目需要确保可以在本地使用LLVM(C/C++编译器使用clang、clang++、Fortran编译器使用flang)编译通过并生成动态库(.so)文件或者可执行文件。

clang是一个C、C++、Objective-C和Objective-C++编程语言的开源编译器前端。

方法一(推荐)

在操作之前需要确保已安装亲和分析功能命令行工具。

  1. 修改构建文件。
    • 替换编译命令:若构建文件中有gcc、g++、gfortran或ld,需要替换成对应的gclang、gclang++、gflang或llvm-link。

      llvm-link不支持链接库文件,若ld命令中存在库文件,请根据所使用的代码语言,使用gclang、gclang++、gflang替换ld命令。

    • 调整编译选项:修改优化等级“-O0”,增加“-g -fno-inline-functions”。
  2. 使用SSH远程登录工具,进入Linux操作系统命令行界面。
  3. 执行以下命令,生成BC文件。

    以下为示例,请用户根据实际情况进行修改。

    devkit advisor bc-gen -i /home/test -c make -o /home/test/bc_files --set-timeout 10 -l 1
    • -i:需要生成BC文件的源码文件夹路径,必选参数。
    • -c:源码的构建命令,必选参数。
    • -o:生成BC文件的存放路径,需要有写权限,可选参数。
    • --set-timeout:任务的超时时间,单位为分钟,若执行时间超过超时时间则退出执行,可选参数。
    • -l:日志级别,默认为1,可选参数。0表示DEBUG;1表示INFO;2表示WARNING;3表示ERROR。

方法二

借助第三方工具gllvm生成BC文件,gllvm是一个基于LLVM的编译器工具链,用于将C/C++代码编译为BC文件,利用gllvm可以简化BC文件的生成流程。

  • gllvm工具使用go编译,并依赖clang编译器,使用详情请参考:https://github.com/SRI-CSL/gllvm/blob/master/README.md,推荐使用1.3.0版本。
  • 使用gllvm工具构建时,需指定编译器类型为gclang、gclang++和gflang,增加编译选项“-g -fno-inline-functions”。

生成BC文件之前请确保系统当前环境满足待测试程序的构建条件。

  1. 将DevKit自带的clang编译器和编译后gllvm工具设置到环境变量中:
    1
    2
    3
    export PATH=/path/DevKit/devkitplugins/affinity/tools/weakconsistency/staticcodeanalyzer/llvm-tools/bin:$PATH
    export PATH=/path/DevKit/devkitplugins/affinity/tools/weakconsistency/staticcodeanalyzer/gllvm-tools:$PATH
    export LD_LIBRARY_PATH=/path/DevKit/devkitplugins/affinity/tools/weakconsistency/staticcodeanalyzer/llvm-tools/lib:$LD_LIBRARY_PATH
    
    • /path:表示DevKit安装目录,请用户根据实际路径进行替换。
    • 若系统中libstdc++版本低于/home/devkit/lib中版本,则需要设置以下环境变量。
      export LD_LIBRARY_PATH=/home/devkit/lib:$LD_LIBRARY_PATH
  2. 设置gllvm对clang和flang的依赖:
    1
    2
    3
    4
    export LLVM_CC_NAME="clang"
    export LLVM_CXX_NAME="clang++"
    export LLVM_FC_NAME="flang"
    export LLVM_LINK_NAME="llvm-link"
    
  3. 优化等级:将待测试工程的所有优化等级都修改为“-O0”。
  4. 构建:将C编译器指定为gclang,C++编译器修改为gclang++,Fortran编译器修改为gflang,同时增加编译选项“-g -fno-inline-functions”,此操作不唯一,与待测试工程的构建工具和参数相关;其他构建步骤不变;可参考以下构建用例:
    • 对于使用脚本构建,但未指定输入参数的工程,以jemalloc为例,可使用如下命令指定编译器类型:
      [root@localhost jemalloc-5.2.1]# CC="gclang" CXX="gclang++" CFLAGS="-g -fno-inline-functions" CXXFLAGS="-g -fno-inline-functions" ./autogen.sh
      autoconf
      ./configure --enable-autogen
      checking for xsltproc.. /usr/bin/xsltproc
      checking	for gcc..	gclang
    • 对于使用脚本构建,但指定输入参数的工程,以incubator-brpc为例,可根据incubator-brpc的参数要求,使用如下命令指定编译器类型:
      [root@localhost incubator-brpc-0.9.6]# sh config_brpc.sh --headers=/usr/include --libs=/usr/lib64 --cc="gclang" --cxx="gclang++" CFLAGS="-g -fno-inline-functions" CXXFLAGS="-g -fno-inline-functions"
      objcopy: st4rvLWw: Failed to find link section for section 8
      objcopy: st4rvLWw: Failed to find link section for section 8
    • 对于使用configure构建的工程,以sqlite为例,可使用如下命令指定编译器类型:
      [root@localhost sqlite-version-3.32.1]# CC="gclang" CXX="gclang++" ./configure CFLAGS="-g -fno-inline-functions" CXXFLAGS="-g -fno-inline-functions"
      checking build system type... aarch64-unknown-Linux-gnu
      checking host system type... aarch64-unknown-linux-gnu
      checking for gcc... gclang
    • 对于在配置文件中指定了编译器类型的工程,需修改配置文件,以bwa为例,使用make构建工具,需将Makefile第一行CC指定为gclang后再执行构建命令。

      修改makefile文件:

      #CC=                        gcc
      CC=                         gclang

      bwa:

      [root@localhost bwa-0.7.17]# make CFLAGS="-g -fno-inline-functions" CXXFLAGS="-g -fno-inline-functions"
      gclang   -c -g -fno-inline-functions -DHAVE_PTHREAD -DUSE_MALLOC_WRAPPERS utils.c -o utils.o
      objcopy: stKUUevi: Failed to find link section for section 15
      objcopy: stKUUevi: Failed to find link section for section 15
      gclang   -c -g -fno-inline-functions -DHAVE_PTHREAD -DUSE_MALLOC_WRAPPERS kthread.c -o kthread.o
      objcopy: stzqwREn: Failed to find link section for section 14
    • 生成BC文件:构建完成后,生成动态库(.so)文件或者可执行文件,使用gllvm的get-bc工具生成BC文件。以jemalloc为例:
      [root@localhost lib]# ls
      libjemalloc.a libjemalloc_pic.a libjemalloc.so libjemalloc.so.2
      [root@localhost lib]# get-bc libjemalloc.so.2
      Bitcode file extracted to: libjemalloc.so.2.bc.
      [root@localhost lib]# ls
      libjemalloc.a libjemalloc_pic.a libjemalloc.so libjemalloc.so.2 libjemalloc.so.2.bc
      [root@localhost lib]#
  5. 打包BC文件。
    1. 创建目录。
      mkdir bcfile
    2. 将bc文件拷贝到目录中。
      cp libjemalloc.so.2.bc bcfile/
    3. 将bc文件打包。
      tar -czvf bcfile.tar.gz bcfile

方法三

使用工程构建工具生成BC文件,如make,cmake等。如果软件使用该方法,需修改相关的配置文件,如makefile。
  • 替换编译命令:若构建文件中有gcc、g++、gfortran或ld,需要替换成对应的clang、clang++、flang或llvm-link。
  • 调整编译选项:修改优化等级“-O0”,增加“-flto -g -fno-inline-functions”。

完成上述操作后,即可通过构建获得BC文件。

  • 在构建项目之前,需将gcc编译器替换成llvm相关的工具。
  • 构建时务必替换或增加指定的编译选项,防止部分指令信息缺失,从而影响分析结果准确性。
  • 将最终生成的目标文件修改为BC文件。
  1. 使用make工具完成项目构建。
    [root@localhost test]# ls
    main.c Makefile test.c
  2. 修改编译命令并替换编译选项。原始的makefile文件和修改后的makefile文件如下所示:

    原始的makefile文件:

    objects=main.o test.o
    exe=case
    
    CFLAGS = -O2 -DAM_CPU_NUMBER=96 -DMAX_PARALLEL_NUMBER=1
    
    all: $(objects)
    
    main.o: ./main.c
            gcc $(CFLAGS) -c $< -o main.o
    test.o: ./test.c
            gcc $(CFLAGS) -c $< -o test.o
    
    all: $(exe)
    case: main.o test.o
            gcc -lpthread main.o test.o -o case
    
    clean:
           rm -f *.o

    修改后的makefile文件:

    objects=main.o test.o
    exe=case.bc
    
    CFLAGS = -O0 -flto -g -fno-inline-functions -DAM_CPU_NUMBER=96 -DMAX_PARALLEL_NUMBER=1
    
    all: $(objects)
    
    main.o: ./main.c
            clang $(CFLAGS) -c $< -o main.o
    test.o: ./test.c
            clang $(CFLAGS) -c $< -o test.o
    
    all: $(exe)
    case.bc: main.o test.o
            llvm-link main.o test.o -o case.bc
    
    clean:
           rm -f *.o

    修改后的makefile文件,将编译工具修改为clang,链接生成目标文件的工具改为llvm-link。

  3. 完成项目构建。
    [root@localhost test]# make
    clang -O0 -flto -g fno-inline-functions -DAM_CPU_NUNBER=96 -DMAX_PARALLEL_NUMBER=1 -c main.c -o main.o
    clang -O0 -flto -g fno-inline-functions -DAM_CPU_NUNBER=96 -DMAX_PARALLEL_NUMBER=1 -c test.c -o test.o
    llvm-link main.o test.o -o case.bc
    [root@localhost test]# ls
    case.bc main.c main.o Makefile test.c test.o
  4. 打包BC文件。
    1. 创建目录。
      mkdir bcfile
    2. 将bc文件拷贝到目录中。
      cp case.bc bcfile/
    3. 将bc文件打包。
      tar -czvf bcfile.tar.gz bcfile
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词