fay59 / fcd Goto Github PK
View Code? Open in Web Editor NEWAn optimizing decompiler
Home Page: http://zneak.github.io/fcd
License: Other
An optimizing decompiler
Home Page: http://zneak.github.io/fcd
License: Other
Functions that use the tail call optimization end with a jmp
instruction instead of a ret
statement. Because of that, fcd will inline the target function instead of calling it and returning its result.
Some links on the gh-pages are broken.
For example, fcd/_posts/2016-02-24-seseloop.markdown contains [1]: {% post_url 2016-02-17-structuring %}
which results in <a href="/2016/02/17/structuring.html">...
(missing /fcd
)
Compare that to <a class="page-link" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
from fcd/_includes/header.html which results in <a class="post-link" href="/fcd/2016/02/17/structuring.html">...
Like here, for example https://github.com/JonathanSalwan/Triton/blob/master/CMakeModules/FindCAPSTONE.cmake
Ubuntu 16.10's gcc
enables PIE builds by default, and stubs come out messed up.
If you attempt to decompile the Question
ELF executable found in this CTF-Challenge:
https://github.com/ctfs/write-ups-2016/tree/master/su-ctf-2016/pwn/login-to-system-200
with the command line fcd -e 0x401182 -e 0x400de4 ./Question
it segfaults.
The core dump shows the problem being a Null-pointer dereference in llvm::PointerType::get where the Type* argument is NULL.
As far as i can tell this occurs because the getIndexedType(ElTy, IdxList) in the getGEPReturnType fails as part of the IdentifyLocals pass.
Is this a bug in LLVM or do you think one of the passes messed up the intermediate code?
I'll try to see if i can find any more information.
The backtrace can be seen here:
#0 0x0000000000b9b484 in llvm::PointerType::get(llvm::Type*, unsigned int) ()
#1 0x000000000053e934 in llvm::GetElementPtrInst::getGEPReturnType (ElTy=0x21baf90, Ptr=0x21d1488, IdxList=...) at /usr/lib/llvm-3.8/include/llvm/IR/Instructions.h:999
#2 0x000000000053e808 in llvm::GetElementPtrInst::GetElementPtrInst (this=0x2285c20, PointeeType=0x21baf90, Ptr=0x21d1488, IdxList=..., Values=2, NameStr=..., InsertBefore=0x219ac40)
at /usr/lib/llvm-3.8/include/llvm/IR/Instructions.h:1068
#3 0x000000000053d957 in llvm::GetElementPtrInst::Create (PointeeType=0x21baf90, Ptr=0x21d1488, IdxList=..., NameStr=..., InsertBefore=0x219ac40) at /usr/lib/llvm-3.8/include/llvm/IR/Instructions.h:876
#4 0x000000000052ab0d in (anonymous namespace)::LlvmStackFrame::getPointerToObject (this=0x1b6d560, object=..., basePointer=0x21d1488, insertionPoint=0x219ac40) at pass_locals.cpp:827
#5 0x00000000005292a8 in (anonymous namespace)::IdentifyLocals::tryToCreateStackFrame (this=0x1ad3a40, fn=...) at pass_locals.cpp:1099
#6 0x0000000000528e73 in (anonymous namespace)::IdentifyLocals::runOnModule (this=0x1ad3a40, m=...) at pass_locals.cpp:996
#7 0x0000000000b8543f in llvm::legacy::PassManagerImpl::run(llvm::Module&) ()
#8 0x00000000004d7c27 in (anonymous namespace)::Main::optimizeAndTransformModule (this=0x7ffc209d73d8, module=..., errorOutput=..., executable=0x1abe3b0) at main.cpp:548
#9 0x00000000004d5dde in main (argc=6, argv=0x7ffc209d7558) at main.cpp:779
Nice catch by clang static analyzer in https://github.com/zneak/fcd/blob/master/fcd/callconv/anyarch_anycc.cpp#L179:
5: Assuming 'load' is non-null in anyarch_anycc.cpp:146
6: 'load' initialized to a null pointer value in anyarch_anycc.cpp:179
7: Called C++ object pointer is null in anyarch_anycc.cpp:181
Also shows -Werror=shadow would be good.
Functions with a single basic block that end in a tail call to a linker stub are confused with linker stubs. This causes a cascade of problems that culminates in that function being replaced with, for instance, a strcmp.47
that has no body and accepts an x86_regs*
as a parameter, while the original function could have had a completely different name and could have done much more than just tail-calling strcmp
.
This is a product of fcd doing a single pass over executables to identify both blocks and functions and produce LLVM IR, and stub identification logic being shoddy.
In the x86_64 System V ABI, the rax
register is used to pass in the number of vector registers that contain parameters. Fcd doesn't know this and proliferates undef
values when that register is read before being set.
struct Base
{
virtual ~Base() = default;
virtual void foo() {}
int a;
};
__attribute__((noinline))
void doSomething(Base* b)
{
b->foo();
}
int main(int argc, const char* argv[])
{
doSomething(new Base);
return 0;
}
<doSomething(Base*)>:
; b->foo();
400680: 48 8b 07 mov rax,QWORD PTR [rdi]
400683: ff 60 10 jmp QWORD PTR [rax+0x10]
<main>:
400690: 50 push rax
400691: bf 10 00 00 00 mov edi,0x10
; doSomething(new Base);
400696: e8 d5 fe ff ff call 400570 <operator new(unsigned long)@plt>
40069b: 48 c7 00 78 07 40 00 mov QWORD PTR [rax],0x400778
4006a2: 48 89 c7 mov rdi,rax
4006a5: e8 d6 ff ff ff call 400680 <doSomething(Base*)>
Specifying a value result with: fcd: for the -flat-org option: Cannot find option named '0x00400000'!
I made some changes to the Makefile:
LLVM_VERSION_SUFFIX =
capstone
from MacPorts, and added -I$(PREFIX)/include/capstone -w
to CXXFLAGS
, where PREFIX = /opt/local
(default install prefix for MacPorts)Then the following error messages were displayed:
command_line.cpp:40:9: error: no matching function for call to 'strncmp'
return strncmp(o.ArgStr, "help", 4) == 0 || strcmp(o.ArgStr, "version") == 0 || optWhitelist->...
^~~~~~~
/usr/include/string.h:84:6: note: candidate function not viable: no known conversion from
'const llvm::StringRef' to 'const char *' for 1st argument
int strncmp(const char *, const char *, size_t);
^
command_line.cpp:40:46: error: no matching function for call to 'strcmp'
return strncmp(o.ArgStr, "help", 4) == 0 || strcmp(o.ArgStr, "version") == 0 || optWhitelist->...
^~~~~~
/usr/include/string.h:77:6: note: candidate function not viable: no known conversion from
'const llvm::StringRef' to 'const char *' for 1st argument
int strcmp(const char *, const char *);
^
2 errors generated.
If I commented this out (i.e. replace with some dummy placeholder like return false
), I receive more compile errors:
In file included from main.cpp:25:
In file included from /fcd/fcd/metadata.h:26:
/fcd/fcd/callconv/params_registry.h:115:23: error: no type named 'ModRefResult' in
'llvm::AAResults'
llvm::AliasAnalysis::ModRefResult getRegisterModRef(const TargetRegisterInfo& reg) const;
~~~~~~~~~~~~~~~~~~~~~^
/fcd/fcd/callconv/params_registry.h:242:10: error: unknown type name 'ModRefResult'
virtual ModRefResult getModRefInfo(llvm::ImmutableCallSite cs, const llvm::MemoryLocation& loc...
^
main.cpp:165:11: error: use of undeclared identifier 'createTypeBasedAliasAnalysisPass'
pm.add(createTypeBasedAliasAnalysisPass());
^
main.cpp:166:11: error: use of undeclared identifier 'createScopedNoAliasAAPass'
pm.add(createScopedNoAliasAAPass());
^
main.cpp:167:11: error: use of undeclared identifier 'createBasicAliasAnalysisPass'; did you mean
'createCostModelAnalysisPass'?
pm.add(createBasicAliasAnalysisPass());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
createCostModelAnalysisPass
/opt/local/libexec/llvm-3.8/include/llvm/Analysis/Passes.h:60:17: note: 'createCostModelAnalysisPass' declared
here
FunctionPass *createCostModelAnalysisPass();
^
main.cpp:433:4: error: use of undeclared identifier 'initializeIPA'; did you mean 'initializeIPO'?
initializeIPA(pr);
^~~~~~~~~~~~~
initializeIPO
/opt/local/libexec/llvm-3.8/include/llvm/InitializePasses.h:47:6: note: 'initializeIPO' declared here
void initializeIPO(PassRegistry&);
^
6 errors generated.
any idea what's wrong / how to fix pls?
Fcd's reaching condition algorithm goes kind of crazy when a block deeply nested in if
conditions jumps over something in the outer scope. For instance, the following program:
#include <stdio.h>
#include <time.h>
int main()
{
putchar(100);
if (time(0) % 2 == 0)
{
putchar(101);
if (time(0) % 3 == 0)
{
putchar(102);
if (time(0) % 5 == 0)
{
putchar(103);
if (time(0) % 7 == 0)
{
puts("foo");
goto end;
}
}
}
}
putchar(104);
end:
putchar(105);
}
decompiles to something like this:
void _main(uint64_t rip)
{
/* ... */
if (anon2)
{
/* ... */
if (anon5)
{
/* ... */
if (anon8)
{
/* ... */
if (anon10 == anon11)
{
_puts((uint8_t*)0x100000fa6);
}
}
}
}
if (anon3 != 0 || anon4 != anon6 && anon2 || anon7 != anon9 && anon2 && anon5 || anon10 != anon11 && anon2 && anon5 && anon8)
{
_putchar(104);
}
_putchar(105);
return;
}
The CFG that looks like this (paste in WebGraphviz if you don't have Graphviz):
digraph unnamed {
Node0x10610e400 [shape=record,label="{10610e400}"];
Node0x10610e400 -> Node0x10610e490;
Node0x10610e400 -> Node0x10610e5b0;
Node0x10610e490 [shape=record,label="{10610e490}"];
Node0x10610e490 -> Node0x10610e520;
Node0x10610e520 [shape=record,label="{10610e520}"];
Node0x10610e5b0 [shape=record,label="{10610e5b0}"];
Node0x10610e5b0 -> Node0x10610e490;
Node0x10610e5b0 -> Node0x10610e640;
Node0x10610e640 [shape=record,label="{10610e640}"];
Node0x10610e640 -> Node0x10610e6d0;
Node0x10610e640 -> Node0x10610e490;
Node0x10610e6d0 [shape=record,label="{10610e6d0}"];
Node0x10610e6d0 -> Node0x10610e760;
Node0x10610e6d0 -> Node0x10610e490;
Node0x10610e760 [shape=record,label="{10610e760}"];
Node0x10610e760 -> Node0x10610e520;
}
A more readable reaching condition would be !anon2 || !anon5 || !anon8 || anon10 != anon11
. Another option, of course, would be !(anon2 && anon5 && anon8 && anon10 == anon11)
. Alternatively, fcd could detect this kind of pattern and use a dispatch variable (dispatch = 0
before the outer if
, dispatch = 1
in the most nested block, dispatch == 0
as the reaching condition).
I've been trying to understand what all the different passes in the default pipeline do. To that end I ran fcd with a partial pipeline on Ubuntu 16.04's /bin/ls
, specifically with
fcd -opt-pipeline="globaldce fixindirects" /bin/ls
This gives me the following errors:
IntToPtr result must be a pointer %8 = inttoptr i64 %7 to i64 IntToPtr result must be a pointer %8 = inttoptr i64 %7 to i64
However if i run fcd normally with only fcd /bin/ls
everything works fine.
Why does this happen? Do the passes leave the LLVM representation in invalid states?
I expect that exception handling is usually supported by a C++ program. I wonder why your function "main" does not contain corresponding try and catch instructions so far.
How do you think about recommendations by Matthew Wilson in an article?
Would you like to adjust the implementation if you consider effects for uncaught/unhandled exceptions like they are described by Danny Kalev?
This has been happening for a while now, I think since move to LLVM 4.
The other tests pass, but fcd crashes while trying to process 1993-ant from the fcd-tests repository:
$ gdb --args fcd ./bin/1993-ant --header ./bin/1993-ant.h -I ./include/ubuntu/usr/include -I ./include/ubuntu/usr/include/x86_64-linux-gnu -I ./include
...
Program received signal SIGSEGV, Segmentation fault.
0x0000000001b5ed74 in llvm::PointerType::get(llvm::Type*, unsigned int) ()
(gdb) bt
#0 0x0000000001b5ed74 in llvm::PointerType::get(llvm::Type*, unsigned int) ()
#1 0x0000000000aa6a24 in llvm::GetElementPtrInst::getGEPReturnType (ElTy=0x4232a30, Ptr=0x3a65378, IdxList=...)
at /nix/store/i218092m9sbfkhcqc2z8lp9n0z66ak32-llvm-4.0.0/include/llvm/IR/Instructions.h:991
#2 0x0000000000ba484b in llvm::GetElementPtrInst::GetElementPtrInst (this=0x3265130, PointeeType=0x4232a30, Ptr=0x3a65378, IdxList=..., Values=2, NameStr=..., InsertBefore=0x31e4b10)
at /nix/store/i218092m9sbfkhcqc2z8lp9n0z66ak32-llvm-4.0.0/include/llvm/IR/Instructions.h:1060
#3 0x0000000000ba39a7 in llvm::GetElementPtrInst::Create (PointeeType=0x4232a30, Ptr=0x3a65378, IdxList=..., NameStr=..., InsertBefore=0x31e4b10)
at /nix/store/i218092m9sbfkhcqc2z8lp9n0z66ak32-llvm-4.0.0/include/llvm/IR/Instructions.h:869
#4 0x0000000000b90c60 in (anonymous namespace)::LlvmStackFrame::getPointerToObject (this=0x35ea890, object=..., basePointer=0x3a65378, insertionPoint=0x31e4b10)
at /tmp/nix-build-fcd-2017-03-28.drv-0/fcd-dc36536744a71aca2846c697b5f4155160d28e7c-src/fcd/pass_locals.cpp:815
#5 0x0000000000b8f46b in (anonymous namespace)::IdentifyLocals::tryToCreateStackFrame (this=0x2b00ca0, fn=...)
at /tmp/nix-build-fcd-2017-03-28.drv-0/fcd-dc36536744a71aca2846c697b5f4155160d28e7c-src/fcd/pass_locals.cpp:1088
#6 0x0000000000b8f063 in (anonymous namespace)::IdentifyLocals::runOnModule (this=0x2b00ca0, m=...)
at /tmp/nix-build-fcd-2017-03-28.drv-0/fcd-dc36536744a71aca2846c697b5f4155160d28e7c-src/fcd/pass_locals.cpp:985
#7 0x0000000001b32eff in llvm::legacy::PassManagerImpl::run(llvm::Module&) ()
#8 0x0000000000b67fca in (anonymous namespace)::Main::optimizeAndTransformModule (this=0x7fffffffb6e8, module=..., errorOutput=..., executable=0x2ac70b0)
at /tmp/nix-build-fcd-2017-03-28.drv-0/fcd-dc36536744a71aca2846c697b5f4155160d28e7c-src/fcd/main.cpp:525
#9 0x0000000000b65b3e in main (argc=10, argv=0x7fffffffb8a8) at /tmp/nix-build-fcd-2017-03-28.drv-0/fcd-dc36536744a71aca2846c697b5f4155160d28e7c-src/fcd/main.cpp:746
I poked at it a bit and this appears to be due to some changes/bug in getIndexedType()
when indexing through a struct but I'm not sure how to best resolve it. Anyway, can you take a look?
(Also--are you seeing the same behavior?)
Thanks!
I'm not able to compile fcd
on Linux, i have the following error:
ast_backend.cpp:346:52: error: ‘successors’ was not declared in this scope
for (auto succ : successors(current->getEntry()))
I'm using the following line:
g++ -std=c++11 -fpermissive -c ast_backend.cpp
Are the intermediate instructions referencing undefined values that are introduced by the sroa pass runs intended? Since SROA is a LLVM pass what makes this happen?
E.g. https://github.com/Lukas-Dresel/fcd/blob/pipelinetesting/pipeline/testing/005_post_sroa.ll#L363
Seems that your Xcode (similar to files created in Visual Studio) creates a lot of whitespace on pressing Enter or something like that...). You can check this project https://github.com/google/google-toolbox-for-mac
Fcd collapses entire strongly-connected components into a single loop, even when distinct, short cycles can be visually identified. This happens in pass_backend.cpp
's ensureSingleEntrySingleExitCycles
. One solution could be to split this function into one that ensures that every cycles have an exit, which would still operate on SCCs, and one that would ensure that loops have a single entry and a single exit, that would operate on regions.
When I tried to build master I got the error:
bindings.cpp:2091:20: error: no matching function for call to 'LLVMBuildLandingPad'
auto callReturn = LLVMBuildLandingPad(self->obj, arg0->obj, arg1, arg2);
It has been checked on gcc 4.8 and 5.3.0, (llvm/clang)-3.7
In Line 405 of callconv/anyarch_anycc.cpp callInfo.getStage() is called without checking if callInfo is nullptr. This can result in a Null-pointer dereference if analysis failed according to comments in callconv/params_registry.cpp
If you tell me what you want the error handling in this case to do i can fix it. When looking at the rest of that function intuitively i would simply add an assertion as is done for the registerInfo in Line 382,
which according to targetinfo.cpp can also be a nullptr if the architecture is not x86.
You can see in my fork of fcd in the branch pipelinetesting under pipeline/testing/test.c that i wrote a very simple, very small program that xors a user-given string with 0x42 and outputs it. Alongside it you can see the output of the print-module calls after every llvm pass completes. When comparing pipeline/testing/10_post_instcombine.ll and pipeline/testing/011_post_gvn.ll we can see that the entire implementation of the main function has been stripped away.
Any ideas why this could be?
P.S. By the way, do you want me to directly link to the files in my fork or reference them like this?
Fcd crashes when it tries to parse a C header that contains a function prototype that has no parameters, like int foo();
. The proper C syntax to mean that foo
takes no parameter is int foo(void);
, but this probably should be fixed.
This is kind of a long-shot, but I think possibly worth it. According to your blog, fcd did not use McSema at the time because it was stuck on LLVM 3.5. Since then, McSema has been re-implemented with the new version 2 and works using on all of LLVM 3.5 through 5.0.
More importantly, though, the actual instruction semantics have been factored out into an independent instruction lifting library, called Remill. Remill supports x86 and x86-64 (with the mmx, x87, sse, and avx instruction sets), as well as aarch64. It is heavily tested, fairly modular, and will be continually supported by Trail of Bits.
If you're interested in this possibility then please let me know!
Hello, I had some trouble building fcd on Arch Linux with LLVM and Clang 3.8 installed.
Firstly, the Makefile contains LLVM_VERSION_SUFFIX = -3.7
on line 6. Since I only have 3.8 installed, and do not have the binaries aliased with the version number, ie things such as llvm-config-3.8
simply do not exist, I set it to LLVM_VERSION_SUFFIX =
(null string), which made it work. However, running make
then produces an error:
make -f /home/wojciech/Downloads/fcd/Makefile.sub -C /home/wojciech/Downloads/fcd/fcd/
make[1]: Entering directory '/home/wojciech/Downloads/fcd/fcd'
clang++ -isystem /usr/include -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -std=c++11 -ffunction-sections -fdata-sections -O3 -DNDEBUG -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/wojciech/Downloads/fcd/fcd/ -I/home/wojciech/Downloads/fcd/fcd/ast/ -I/home/wojciech/Downloads/fcd/fcd/callconv/ -I/home/wojciech/Downloads/fcd/fcd/codegen/ -I/home/wojciech/Downloads/fcd/fcd/cpu/ -I/home/wojciech/Downloads/fcd/fcd/executables/ -I/home/wojciech/Downloads/fcd/fcd/llvm-gvn-rewrite/ -I/home/wojciech/Downloads/fcd/fcd/python/ -isystem /home/wojciech/Downloads/fcd/build/includes -isystem /usr/include/capstone -Wall -Wunreachable-code -Wempty-body -Wconditional-uninitialized -Werror=conversion -Wno-error=sign-conversion -Winvalid-offsetof -Wnewline-eof --std=gnu++14 -fno-rtti -c -o /home/wojciech/Downloads/fcd/build/pass_regaa.o pass_regaa.cpp
warning: unknown warning option '-Wno-maybe-uninitialized'; did you mean '-Wno-uninitialized'? [-Wunknown-warning-option]
In file included from pass_regaa.cpp:27:
In file included from /home/wojciech/Downloads/fcd/fcd/metadata.h:26:
In file included from /home/wojciech/Downloads/fcd/fcd/callconv/params_registry.h:26:
In file included from /home/wojciech/Downloads/fcd/fcd/targetinfo.h:28:
In file included from /usr/include/llvm/IR/DataLayout.h:23:
In file included from /usr/include/llvm/ADT/DenseMap.h:17:
In file included from /usr/include/llvm/ADT/DenseMapInfo.h:17:
In file included from /usr/include/llvm/ADT/ArrayRef.h:13:
In file included from /usr/include/llvm/ADT/Hashing.h:48:
In file included from /usr/include/llvm/Support/DataTypes.h:35:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../include/c++/6.1.1/cmath:45:15: fatal error: 'math.h' file not found
#include_next <math.h>
^
1 warning and 1 error generated.
/home/wojciech/Downloads/fcd/Makefile.sub:12: recipe for target '/home/wojciech/Downloads/fcd/build/pass_regaa.o' failed
make[1]: *** [/home/wojciech/Downloads/fcd/build/pass_regaa.o] Error 1
make[1]: Leaving directory '/home/wojciech/Downloads/fcd/fcd'
Makefile:44: recipe for target '/home/wojciech/Downloads/fcd/fcd/' failed
make: *** [/home/wojciech/Downloads/fcd/fcd/] Error 2
At this point I gave up on the Makefile and tried CMake like this:
mkdir build
cd build
cmake ..
make
The CMakeLists.txt file is unfortunately also erroneous, but I managed to make it build with two fixes. First, on line 41, I had to add -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
, since without that this happens:
[ 4%] Generating bindings.cpp
In file included from /usr/include/llvm-c/Core.h:18:
In file included from /usr/include/llvm-c/ErrorHandling.h:17:
In file included from /usr/include/llvm-c/Types.h:17:
/usr/include/llvm/Support/DataTypes.h:57:3: error: "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
^
/usr/include/llvm/Support/DataTypes.h:61:3: error: "Must #define __STDC_CONSTANT_MACROS before " "#including Support/DataTypes.h"
#17 error "Must #define __STDC_CONSTANT_MACROS before " \
Then, on the same line (41), python
has to be switched to python2.7
, since Python 3 is the default on my system. Otherwise the script python/bindings.py
fails with
File "/home/wojciech/Downloads/fcd/fcd/python/bindings.py", line 143
raise ValueError, "callback type %s" % cFunction.returnType
The above two changes make it build, but I won't put them in a PR since I'm unsure whether they actually produce a correct binary - running what I built on a braindead-simple C++ app from this source with clang++ -g main.cpp -o ack2
:
int main(int argc, char** argv) {
int a = 20;
int c = a + 4;
return 0;
}
like ./fcd ack2
results in a segfault :/
I would like to point out that identifiers like "fcd__metadata_h
" and "fcd__targetinfo_h
" do not fit to the expected naming convention of the C++ language standard.
Would you like to adjust your selection for unique names?
LLVM 3.9 made it to public package repositories some time ago. I've just updated the Makefile, but CMake remains behind.
Hello. I've just built fcd and a Go's hello world, and tried to decompile the hello-world with fcd. As result it's a segfault:
$ cat helloworld.go
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
$ go version
go version go1.7.4 linux/amd64
$ go build
$ ~/src/fcd/build/fcd hello
Stack dump:
0. Optimizing LLVM IR
1. Running pass 'Identify locals' on module 'hello'.
0 libLLVM-4.0.so.1 0x00007f35f6b7cbc5 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1 libLLVM-4.0.so.1 0x00007f35f6b7ad6e llvm::sys::RunSignalHandlers() + 62
2 libLLVM-4.0.so.1 0x00007f35f6b7ae92
3 libc.so.6 0x00007f35f3495060
4 libLLVM-4.0.so.1 0x00007f35f6c6edb4 llvm::PointerType::get(llvm::Type*, unsigned int) + 20
5 fcd 0x0000000000960b44 llvm::GetElementPtrInst::getGEPReturnType(llvm::Type*, llvm::Value*, llvm::ArrayRef<llvm::Value*>) + 100
6 fcd 0x0000000000a5dd3b llvm::GetElementPtrInst::GetElementPtrInst(llvm::Type*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::Twine const&, llvm::Instruction*) + 123
7 fcd 0x0000000000a5ce97
8 fcd 0x0000000000a4a530
9 fcd 0x0000000000a48d3b
10 fcd 0x0000000000a48933
11 libLLVM-4.0.so.1 0x00007f35f6c43007 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 759
12 fcd 0x0000000000a21acc
13 fcd 0x0000000000a1f61d main + 2957
14 libc.so.6 0x00007f35f34822e1 __libc_start_main + 241
15 fcd 0x0000000000879b7a _start + 42
Segmentation fault (core dumped)
PEP 394 recommends the usage of python2
when invoking Python 2 scripts instead of python
, as the latter might be different depending on the distribution (and indeed it is - it's Python 3 in Arch Linux).
You can see in my fork of fcd in the branch pipelinetesting under pipeline/testing/test.c that i wrote a very simple, very small program that xors a user-given string with 0x42 and outputs it. Alongside it you can see the output of the print-module calls after every llvm pass completes. When comparing pipeline/testing/011_post_gvn.ll and 012_post_simplify_cfg.ll we can see that the entire implementation of the main function has been stripped away.
P.S. By the way, do you want me to directly link to the files in my fork or reference them like this?
The parameters to calls to variadic functions, such as printf, are omitted by fcd.
Like in C99/C++ vs. older C.
Just tested a quick hack removing the decl block and adding the type to the token returned by FunctionNode::createDeclaration(Type &type, const string& declName)
.
Already better, but of course also affects further usages. DeclarationStatement would need to be transformed somehow.
btw very nifty approach using a normal emulator instead of the usual cumbersome llvm API code 👍
Hi,
I'm using clang 3.7.1 but the compilation failed, which says that LLVMBuildLandingPad
(https://github.com/zneak/fcd/blob/master/fcd/python/bindings.cpp#L2091) requires 5 arguments while 4 provided. Then I searched and found that the signature of this function has been changed:
http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/lang/clang/Makefile.common?rev=1.11&content-type=text/x-cvsweb-markup
It seems that the function would need 4 arguments only in clang 3.7.0, and I'm wondering if it would be better to change the code accordingly.
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.