Are there any good resources on interpreting the AST output of clang? - clang

I'm trying to make sense of clang's AST output and can't really find any enlightenment on the web.
Yes, there is this page but its content is very limited and I can't really do much with their Doxygen documentation.
Command I'm using to generate the AST is:
$ clang -Xclang -ast-dump=json -fsyntax-only file.c

Related

LLVM - Run concrete pass with clang [duplicate]

I am working on LLVM obfuscation project. I have written a llvm pass(lets say flow flattening pass) which i am running on source (test.c) with following command:
clang -emit-llvm test.c -c -o test.bc
opt -load ../../.. LLVMFlattening.so -fla <test.bc>/dev/null
But i have seen that in O-LLVM project they achieved same thing using:
clang -emit-llvm test.c -c -o test.bc -mllvm -fla
Can someone tell me what is -mllvm here and how this changed to a simple command?
-mllvm means Additional arguments to forward to LLVM's option processing. Therefore -mllvm -fla will pass -fla to the LLVM's option processing.
Clang and LLVM could run seperately. If you want clang to run llvm, and also have some options which you want llvm to aware. -mllvm is what you need.
Defautly, LLVM does not turn on all the transformation passes. With -fla, LLVM will turn on the pass registered with command line argument fla by call function RegisterPass<typename passName>.
In your command line, opt's -load option is used to load plugin. If you want to use the simple command line as expect. Your pass need to be linked into the opt binary. This could be done in the following two ways:
(Without modify the existing LLVM source tree): Add your only pass's source by adding CMakeLists.txt mentioned in this link
Directly copy your pass source code folder into <LLVM root>/lib/Transform directory. And modify the <LLVM root>/lib/Transform/CMakeLists.txt, add add_subdirectory(<pass name>) line just like others.
I'm working on O-LLVM rencently, and came into the same problem. Here is my solution:
1.add static cl::opt<bool> YOUR_FLA("fla", cl::init(false),"info...") to PassManagerBuilder.cpp
2.add function Pass *createYOUR_FLA(bool flag) in your obfuscation pass source code
3.add MPM.add(createYOUR_FLA(YOUR_FLA)); to function populateModulePassManager in PassManagerBuilder.cpp
The solution above works with my simple pass.

Clang and llc with --x86-asm-syntax=intel produce AT&T syntax

Below are two command line strings I used to output to assembly language listing using --x86-asm-syntax=intel. Both command line strings work, but they both produce AT&T syntax, not Intel syntax.
sudo clang-8 -S -mllvm --x86-asm-syntax=intel Svx.c
sudo llc-8 --x86-asm-syntax=intel Svx.ll -o Svx.s
at the top of each file it says:
.intel_syntax noprefix
But the code it produces is AT&T syntax.
I've researched and haven't found an answer.
Thanks for any ideas on why these command strings do not produce Intel syntax.

clang-3.8 and compiler-rt vs libgcc

I have been using clang-3.5 to happily build bitcode versions of musl libc and
use the result to produce nice stand alone executables.
Recent attempts with clang-3.8 have not been so happy. It seems that
the bitcode clang-3.8 generates uses functions defined in
compiler-rt/lib/builtins
Typical examples of functions I find polluting the bitcode are mulxc3, mulsc3, and muldc3. I can solve this by linking against libgcc, or even the llvm alternative if I had any clear idea of what that was. Though I would rather prevent the problem from happening in the first place.
I have seen mention of flags like rtlib=compiler-rt etc, but have found precious little documentation on the subject.
So here are some simple questions.
Is it possible to prevent clang from using the compiler-rt/lib/builtins
in the emitted bitcode? Or if not
Does llvm produce a version of libgcc that I could use. Actually I would
probably build a bitcode version of it, but that is besides the point.
Love to hear some guidance on this.
Added 12/8/2016: So I will illustrate my issues with a particular workflow that
people can reproduce if they wish, or, more likely, just point out where I am being stupid.
So start by checking out:
musllv
and follow the instructions in the README.to compile (here I am using clang-3.8 on ubuntu 14.04)
WLLVM_CONFIGURE_ONLY=1 CC=wllvm ./configure --target=LLVM --build=LLVM
make
cd lib
extract-bc -b libc.a
you will also need the bitcode of a simple executable. I will use nweb.c here.
wllvm nweb.c -o nweb
extract-bc nweb
Now we can do things like:
clang -static -nostdlib nweb.bc libc.a.bc crt1.o libc.a -o nweb
This workflow goes smoothly for clang-3.5 but for clang-3.8 we get:
clang -static -nostdlib nweb.bc libc.a.bc crt1.o libc.a -o nweb
/tmp/libc-f734a3.o: In function `cpowl':
libc.a.bc:(.text+0xbb9a): undefined reference to `__mulxc3'
/tmp/libc-f734a3.o: In function `cpowf':
libc.a.bc:(.text+0x38f7d): undefined reference to `__mulsc3'
/tmp/libc-f734a3.o: In function `csqrt':
libc.a.bc:(.text+0x78fc3): undefined reference to `__muldc3'
/tmp/libc-f734a3.o: In function `cpow':
libc.a.bc:(.text+0xafafc): undefined reference to `__muldc3'
clang-3.8: error: linker command failed with exit code 1 (use -v to seeinvocation)
So as #paul-brannan points out we could try
clang -static -nostdlib --rtlib=compiler-rt nweb.bc libc.a.bc crt1.o libc.a -o nweb
But this is where I am probably being stupid, because I get:
clang-3.8: warning: argument unused during compilation: '--rtlib=compiler-rt'
irregardless of whether I use it as a linking or compiling flag.
OK so I finally managed to make headway on this. I built llvm-3.8.1 together with the compiler-rt project using wllvm and wllvm++.
One of the build products was libclang_rt.builtins-x86_64.a,
and from this archive I was able to extract the bitcode module
libclang_rt.builtins-x86_64.bc
using the command:
extract-bc -b libclang_rt.builtins-x86_64.a
This bitcode module has definitions for those pesky instrinsics like
__mulxc3, __mulsc3, and __muldc3.
Hallelujah!

clang: cancel effect of the -x option for subsequent files

clang has an option, -x, which can be used to specify the language of subsequent source files passed to it. This caused problems when used like this:
clang -x c++ one.cc a.o b.o c.o
clang will try to interpret the object files a.o, b.o, c.o as source code.
Is there a way to cancel the effect of the -x option so I can pass object files on the same command line?
clang -x c++ one.cc SOMEOPTION a.o b.o c.o
What should SOMEOPTION be to allow clang to interpret the .o files as object files?
I need to use this convoluted command line because I am using a system that calls the compiler automatically to compile some code it generates and there are limits to how much it can be hacked.
could you put the arguments the other way 'round
clang a.o b.o c.o -x c++ one.cc
or compile each file and then link them in a later run
clang -x c++ one.cc -o one.cc.o
clang a.o b.o c.o one.cc.o
This is how in my experience it is actualy used.

How to view Clang AST?

I am trying to get hold on Clang. So, I would like to view the AST generated by Clang after parsing the given program. Is it possible to dump AST in .dot or .viz format? Is there any tool out there?
The method with -cc1 invocation will have problem with includes and recognizing C++.
For full-featured parsing, use:
clang -Xclang -ast-dump file.cpp
Clang supports showing the AST with Graphviz's dotty -- you can grab the temporary .dot file generated (name is printed out) to get the graph source.
clang -cc1 -ast-view your_file.c
You can also print to the command line with:
clang -cc1 -ast-dump your_file.c
or:
clang -cc1 -ast-print your_file.c
or in 3.3:
clang -cc1 -ast-dump-xml your_file.c
but this was removed later as pointed by Lukas Kubanek in the comment.
For viewing the AST
clang-check -ast-dump filename.c
For to view the specific functions in a program
clang-check -ast-dump -ast-dump-filter=function_name filename.c
I am using following:
clang my_file.h -I. -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics -Wno-visibility
IMHO This is more suitable for machine parsing.

Resources