Skip to content

Commit

Permalink
README update
Browse files Browse the repository at this point in the history
  • Loading branch information
examon committed Dec 11, 2018
1 parent ed5202e commit 384025b
Show file tree
Hide file tree
Showing 49 changed files with 4,450 additions and 204 deletions.
15 changes: 0 additions & 15 deletions DOC.md

This file was deleted.

65 changes: 37 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# OUTDATED

# APEX - Active code Path EXtractor

APEX is a tool that can extract active code path from the C program source code
Expand All @@ -12,46 +10,57 @@ In order to run APEX, you need to have llvm installed:
- https://llvm.org/docs/GettingStarted.html
- https://releases.llvm.org/3.8.0/docs/CMake.html

If you want to build LLVM from source, run:
``` shell
cd src
./build_llvm.sh
```

After getting LLVM, APEX needs to be built. Run the following command
to build APEX:
``` shell
make build
```

### How to run APEX

Input C source code is located in the [test.c](c-code/test.c). <br>
Source and target functions defining start and end of the active code path can
be specified in the [apex.h](apex/apex.h).
First, you need to compile your C program into LLVM bitcode since APEX cannot
work directly with the C source code.

After providing input, run `make run`. Check `apex/build` for output.
``` bash
clang -c -g -emit-llvm main.c -o main.bc
```

After obtaining bitcode, we can now run APEX via `apex.py` launcher:

### How it works
```
python apex.py main.bc main.c 16
```

Let's say we have C source file [test.c](c-code/test.c) and we want to
extract active path between functions `main` and `y` (we specify these inputs
according to the instructions above).
`apex.py` requires three arguments. See usage for full description:

After running `make run`, APEX:
- uses llvm and translates `test.c` into IR (intermediate representation)
- creates call graph from the IR
- finds some active code path from source (`main`) to target (`y`)
- removes functions that are not on the active code path
``` bash
usage: apex.py [-h] [--export EXPORT] code file line

To run extracted active code path, type `lli apex/build/bytecode_from_input_basic_opts_and_apex.bc`
(see [build_and_run.sh](build_and_run.sh) script for more info).
positional arguments:
code C source code compiled into LLVM bytecode.
file Target file name (NOT FULL PATH).
line Target line number.

Image on the left represents call graph before we run APEX, while image on the
right shows how the call graph looks after APEX transformed IR. <br>
optional arguments:
-h, --help show this help message and exit
--export EXPORT true/false for exporting call graphs.
```

![](img/callgraph_default_opt.dot.svg) ![](img/callgraph_apex.dot.svg)
APEX produces extracted executable called `extracted` along with the `build`
directory (containing various files, logs, etc.).


### Current limitations:

Since APEX is under development, there are currently some serious limitations:

```
- supports only one compilation module
- handles only void returning functions on the active path
- does not handle external libraries
- (probably tons more that I don't know about)
```

[TODO](TODO.md) | [DOC](DOC.md)
- It is possible to extract values only from integer variables.
- APEX can handle small programs (see examples direcotry), but may have problems
with bigger ones.
- (Probably tons more that I don't know about.)
10 changes: 0 additions & 10 deletions TODO.md

This file was deleted.

Binary file added examples/domainname/domainname.bc
Binary file not shown.
44 changes: 44 additions & 0 deletions examples/domainname/domainname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

char *__progname;
void usage(void);

int
main(int argc, char *argv[])
{
int ch;
char domainname[HOST_NAME_MAX+1];

while ((ch = getopt(argc, argv, "")) != -1)
switch (ch) {
default:
usage();
}
argc -= optind;
argv += optind;

if (argc > 1)
usage();

if (*argv) {
if (setdomainname(*argv, strlen(*argv)))
err(1, "setdomainname");
} else {
if (getdomainname(domainname, sizeof(domainname)))
err(1, "getdomainname");
(void)printf("%s\n", domainname);
}
return(0);
}


void usage(void)
{
(void)fprintf(stderr, "usage: %s [name-of-domain]\n", __progname);
exit(1);
}
6 changes: 0 additions & 6 deletions examples/example/Makefile

This file was deleted.

Binary file removed examples/example/example.bc
Binary file not shown.
17 changes: 0 additions & 17 deletions examples/example/example.c

This file was deleted.

98 changes: 0 additions & 98 deletions examples/example/example.ll

This file was deleted.

6 changes: 0 additions & 6 deletions examples/example_mod1/Makefile

This file was deleted.

Binary file removed examples/example_mod1/example_mod1.bc
Binary file not shown.
Binary file added examples/example_mod2/example_mod2.bc
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ int foo(int n) {
}

int qux(void) {
return 42;
return 42;
}

int bar(void) {
Expand All @@ -13,9 +13,11 @@ int bar(void) {
}

int main(void) {
int some_int = 10;
int foo_result = foo(some_int);
int bar_result = bar();

int some_int = 10;
int foo_result = foo(some_int);
int n = 10;
if (n < 42) {
int bar_result = bar();
}
return 0;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; ModuleID = '../examples/mod1/example_mod1.bc'
source_filename = "example_mod1.c"
; ModuleID = 'example_mod2.bc'
source_filename = "example_mod2.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

Expand Down Expand Up @@ -44,6 +44,7 @@ entry:
%retval = alloca i32, align 4
%some_int = alloca i32, align 4
%foo_result = alloca i32, align 4
%n = alloca i32, align 4
%bar_result = alloca i32, align 4
store i32 0, i32* %retval, align 4
call void @llvm.dbg.declare(metadata i32* %some_int, metadata !31, metadata !12), !dbg !32
Expand All @@ -52,10 +53,20 @@ entry:
%0 = load i32, i32* %some_int, align 4, !dbg !35
%call = call i32 @foo(i32 %0), !dbg !36
store i32 %call, i32* %foo_result, align 4, !dbg !34
call void @llvm.dbg.declare(metadata i32* %bar_result, metadata !37, metadata !12), !dbg !38
%call1 = call i32 @bar(), !dbg !39
store i32 %call1, i32* %bar_result, align 4, !dbg !38
ret i32 0, !dbg !40
call void @llvm.dbg.declare(metadata i32* %n, metadata !37, metadata !12), !dbg !38
store i32 10, i32* %n, align 4, !dbg !38
%1 = load i32, i32* %n, align 4, !dbg !39
%cmp = icmp slt i32 %1, 42, !dbg !41
br i1 %cmp, label %if.then, label %if.end, !dbg !42

if.then: ; preds = %entry
call void @llvm.dbg.declare(metadata i32* %bar_result, metadata !43, metadata !12), !dbg !45
%call1 = call i32 @bar(), !dbg !46
store i32 %call1, i32* %bar_result, align 4, !dbg !45
br label %if.end, !dbg !47

if.end: ; preds = %if.then, %entry
ret i32 0, !dbg !48
}

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
Expand All @@ -66,7 +77,7 @@ attributes #1 = { nounwind readnone speculatable }
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.1 (tags/RELEASE_500/final)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "example_mod1.c", directory: "/mnt/Documents/work/university/muni/msc/thesis/APEX/examples/mod1")
!1 = !DIFile(filename: "example_mod2.c", directory: "/mnt/Documents/work/university/muni/msc/thesis/APEX/examples/experiments/example_mod2")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
Expand Down Expand Up @@ -97,12 +108,20 @@ attributes #1 = { nounwind readnone speculatable }
!29 = !DILocation(line: 12, column: 5, scope: !24)
!30 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !21, isLocal: false, isDefinition: true, scopeLine: 15, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
!31 = !DILocalVariable(name: "some_int", scope: !30, file: !1, line: 16, type: !10)
!32 = !DILocation(line: 16, column: 9, scope: !30)
!32 = !DILocation(line: 16, column: 7, scope: !30)
!33 = !DILocalVariable(name: "foo_result", scope: !30, file: !1, line: 17, type: !10)
!34 = !DILocation(line: 17, column: 9, scope: !30)
!35 = !DILocation(line: 17, column: 26, scope: !30)
!36 = !DILocation(line: 17, column: 22, scope: !30)
!37 = !DILocalVariable(name: "bar_result", scope: !30, file: !1, line: 18, type: !10)
!38 = !DILocation(line: 18, column: 9, scope: !30)
!39 = !DILocation(line: 18, column: 22, scope: !30)
!40 = !DILocation(line: 20, column: 5, scope: !30)
!34 = !DILocation(line: 17, column: 7, scope: !30)
!35 = !DILocation(line: 17, column: 24, scope: !30)
!36 = !DILocation(line: 17, column: 20, scope: !30)
!37 = !DILocalVariable(name: "n", scope: !30, file: !1, line: 18, type: !10)
!38 = !DILocation(line: 18, column: 7, scope: !30)
!39 = !DILocation(line: 19, column: 7, scope: !40)
!40 = distinct !DILexicalBlock(scope: !30, file: !1, line: 19, column: 7)
!41 = !DILocation(line: 19, column: 9, scope: !40)
!42 = !DILocation(line: 19, column: 7, scope: !30)
!43 = !DILocalVariable(name: "bar_result", scope: !44, file: !1, line: 20, type: !10)
!44 = distinct !DILexicalBlock(scope: !40, file: !1, line: 19, column: 15)
!45 = !DILocation(line: 20, column: 7, scope: !44)
!46 = !DILocation(line: 20, column: 20, scope: !44)
!47 = !DILocation(line: 21, column: 2, scope: !44)
!48 = !DILocation(line: 22, column: 5, scope: !30)
Binary file added examples/example_mod2/example_mod2_nodbg.bc
Binary file not shown.
Loading

0 comments on commit 384025b

Please sign in to comment.