2020/11/3

clang, disable optimize for latter pass

這一篇,用 llvm-11 的話,opt 的指令沒有效。
stack overflow 有說。
在 compile 時,如果沒有加上 -O,在產生的 ll file, function 錢會有 optnone,避免 reg2mem 做 optimization:
; Function Attrs: noinline nounwind optnone uwtable
define i32 @add(i32, i32) #0 {
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  store i32 %0, i32* %3, align 4
所以 compile 時要加場上 -O
clang -S -emit-llvm -O  main.c
這樣就不會有 optnone 的標記:
; Function Attrs: norecurse nounwind readnone uwtable
define i32 @add(i32, i32) local_unnamed_addr #0 {
  %3 = add nsw i32 %1, %0
  ret i32 %3
}
但是也optimize 過了...

如果不要他先 optimize,又要加
clang -S -emit-llvm -O -Xclang -disable-llvm-passes main.c
這樣才能完成跟街學文章一樣的code
; Function Attrs: nounwind uwtable
define i32 @add(i32, i32) #0 {
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  store i32 %0, i32* %3, align 4, !tbaa !2
  store i32 %1, i32* %4, align 4, !tbaa !2
  %5 = load i32, i32* %3, align 4, !tbaa !2



最後,用 as 和 ld link 出 exeutable file,
要指定 crt1.o, crti.o,但是最終還是無法執行。

可能是 default library 的關係。
用 gcc assembly front-end 舊可以..
gcc main.s -no-pie -o main
用 -v 可以看一下 gcc ld 的 default crt.o 和 library
或許照著寫舊可以用 ld 成功 link..

這一篇 就是這樣做
ld -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 test.o  /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/gcc/x86_64-linux/4.3/crtbegin.o -lc /usr/lib64/gcc/x86_64-linux/4.3/crtend.o /usr/lib64/crtn.o
用了 ld-linux-x86-64.so crti.o crtbegin.o

依照 error mesaage,最後。minimum:
ld main.o /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o -lc
但是link 出來的 a.out 執行出現 'No such file or directory'

這一篇 的回答好像才是重點,interpreter 的問題。
用 gcc compile 的 a.out 和 ld link 出來的 a.out,用 readelf -l 看, interpreter 不一樣。

用 patchelf 的話..
$ patchelf --print-interpreter a.out 
/lib/ld64.so.1
$ patchelf --print-interpreter gmain 
/lib64/ld-linux-x86-64.so.2
不一樣。
實際上沒有 /lib/ld64.so.1
所以 Error message 是 'No sunch file or directory'

用 patchelf 設定正確的 interpreter;
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 a.out 
所以。最後,正確 ld 的 command 是:
ld -o a.out -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o -lc  /usr/lib/x86_64-linux-gnu/crtn.o main.

這一篇 有詳細講crtX.o 和 interpreter 之間的關係和實驗。

沒有留言:

張貼留言