其他分享
首页 > 其他分享> > LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

作者:互联网

一 、概念介绍:LLVM和OLLVM

注:即使不用ollvm,LLVM本身也是有很多pass的,具体的类型主要有以下几种

二、官方LLVM和其Clang

1.安装

官方下载llvm,下载源码包,官方把llvm和clang分开,需要把llvm和clang源码包都下载下来。

解压,改clang的包名,移动至llvm的tools下。
在llvm同级目录新建build目录,cd build

cmake -G "Unix Makefiles" --enable-optimized -DCMAKE_BUILD_TYPE=Release ../llvm-5.0.2.src

2.使用clang编译.c文件

源代码:

#include<stdio.h>
int main() {
        int a  = 4,b = 5;
        printf("a+b=%d",a+b);
        printf("hello world\n");
        return 0;
}

通过上面的实践,观察ll文件和elf文件的变化,可以得出结论:

通过 -fembed-bitcode 参数,clang把对应的bitcode文件整个嵌入到了object文件中

注:

非Archive类型的build,比如直接⌘ + B,即使开启了bitcode,也不会编出bitcode,那么会产生什么样的文件呢?通过观察编译日志可以看出xcode在此时使用了-fembed-bitcode-marker 这样一个参数,我们来试一下:

`$ clang -fembed-bitcode-marker -c test.c -o test_bitcode_marker.o $ otool -l test_bitcode_marker.o # 以下为otool输出节选 Section   sectname __bitcode    segname __LLVM       addr 0x0000000000000039       size 0x0000000000000001    # 只有一个字节     offset 769      align 2^0 (1)     reloff 0     nreloc 0      flags 0x00000000 $ objdump -s -section=__bitcode test_bitcode_marker.o Contents of section __bitcode:  0039 00                                   . # 只有一个字节 0x00 `

这样的方式编译出的文件结构与-fembed-bitcode 的结果是一样的,唯一的区别就是 __LLVM,__bitcode__LLVM,__cmdline 的内容并没有将实际的bitcode文件和编译参数嵌入进来,取而代之的一个字节的占位符 0x00

三、第三方LLVM(OLLVM)编译器和其Clang

1.安装

与官方LLVM安装方式一致,唯一区别就是不用下载clang移至llvm下,因为Ollvm包含了clang,直接编译即可。

Obfuscator-LLVM下载地址

编译命令:cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator-llvm-4.0

2.使用第三方clang编译.c文件

四、LLVM和OLLVM的Clang编译结果diff

五、Bitcode相关介绍

1.编码格式

在Diff使用不使用-fembed-bitcode产生的目标文件时,看到了新增的很多16进制信息,(__LLVM信息),而这些Bitcode信息的编码格式与Bytecode并不相同。Bitcode是按bit存取的,而不是byte(8bits),最大化的利用空间。具体可以参考官方文档;

2.Bitcode兼容性

bitcode的格式目前是一直在变化的,并且无法向前兼容,举例来说Xcode8的编译器无法读取并解析xcode9产生的bitcode。现在最新的编译器已经到了Xcode11。

另外苹果的bitcode格式与社区版LLVM的bitcode有一定差异,但苹果并不会及时开源Xcode最新版编译器的代码,所以如果你使用第三方基于社区版LLVM制作的编译器进行开发,不要尝试开启并提交bitcode到App Store Connect,否则会因为App Store Connect解析不了你的bitcode而被拒。
Xcode9之前通过添加ideplugin使用Ollvm,xcode10之后无法使用添加ideplugin的方法,但添加编译链跑的依然可行 ,但是最新的 Xcode10 通过非官方默认的 Toolchains 编译后的的 ipa 是拒绝提交审核的。因此对于Bitcode和Ollvm要进行鱼和熊掌一样的取舍。

3.Bitcode不是架构无关的代码

如果一个app同时要支持armv7和arm64两种架构,那么同一个源代码文件将会被编译出两份bitcode,也就是说,在一开始介绍LLVM的那张图中,并不是代表同一份bitcode代码可以直接被编译为不同目标机器的机器码。

LLVM只是统一了中间语言的结构和语法格式,但不能像Java那样,Compile Once & Run Everywhere.

4.判断是否开启Bitcode

可以通过otool检查二进制文件,网上有很多类似这样的方法:
otool -arch armv7 -l xxxx.a | grep __LLVM | wc -l

通过判断是否包含 __LLVM 或者关键字来判断是否支持bitcode,其实这种方式是完全错误的,通过前面的测试可以知道,这种方式区分不了bitcode和bitcode-marker,确定是否包含bitcode,还需要检查otool输出中__LLVM Segment 的长度,如果长度只有1个字节,则并不能代表真正开启了bitcode:

$ otool -l test_bitcode.o | grep -A 2  __LLVM | grep size
      size 0x0000000000000b10
      size 0x0000000000000042
$ otool -l test_bitcode_marker.o | grep -A 2  __LLVM | grep size
      size 0x0000000000000001
      size 0x0000000000000001

参考:ollvm快速学习
关于bitcode,知道这些就够了
别动我的代码!聊聊那些代码保护的艺术
[Xcode混淆实战]([https://github.com/huanglins/iOSObfuscator/blob/master/iOS%20%E9%A9%AC%E7%94%B2%E5%8C%85%E3%80%81%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86%E3%80%81%E7%BC%96%E8%AF%91%E6%B7%B7%E6%B7%86%E5%AE%9E%E8%B7%B5.md](https://github.com/huanglins/iOSObfuscator/blob/master/iOS 马甲包、代码混淆、编译混淆实践.md))

JXNUleo 发布了23 篇原创文章 · 获赞 7 · 访问量 8万+ 私信 关注

标签:Bitcode,00,LLVM,false,编译器,A1,1C,1E,1D
来源: https://blog.csdn.net/m0_37874657/article/details/104187887