Test suite v2 (#589)

* Parse flavors

* Batch folder is now created/deleted properly

* Shared libraries as symlinks in special dir

* Simple README file

* Get binary info

* Simple cfg retrieval

* Lifter has path to cfg as argument

* Flags for eventual evaluation

* Check policy and presence of cfg file

* Print results of getting the cfgs

* Check of batch sanity fix

* run_test cli parsing

* Add abi_libraries directory parsing

* Shared libraries directory parsing

* Lift and recompile

* Before actual test implementation

* Playground for testing

* Actual testing

* Split test cases on per binary bases

* Add some commits

* Result print

* Enhance README.txt

* Populate.py to copy needed binaries

* Add short decsription of populate.py

* Support flavor all

* add ida frontend implementation

* Basic tag files

* Basic inputs

* Missing comma

* Change inputs handling

* Separate function for copy files

* Naming convention

* Handle missing test case class

* Create bin if it is missing

* Create so_dir if it is missing

* Remove not used cmd argument

* Add several more test_suites

* ida frontend lift function can now be selected

* Smarter tests

* BasicTest does not need setUp

* Prevent system-wide installed binaries from being run instead of tested

* Simple comment

* Pass rest of are passed to lift

* Fix parser error with unspecified lift_args

* Variable name

* Change default interpreter to python3

* Fix optional argument parsing for the subsequent lift

* typo in mcsema-disass

* More details in README

* Simplify usage of IDA frontend

* ida frontend stores logs

* Add script to compile programs and generate tags if desired

* Year on copyright

* Add hello world src examples of tests.

* Add test addition example to README

* Correct extension for log files

* Basic linker flags

* Fix crash if file in bin is missing when tag is present

* Bunch of test files

* Empty runs

* Test_suite name should have maxsplit=1

* Dynamically create test_suites for src programs from definitions

* Define cases

* Stdin

* Split tests into another file

* WIP: stdin from string

* Another string to be matched if binary is pie

* Fix typo in test case

* Add color support

* Improve stdout output

* Add wrappers to make colors more use friendly

* Move object representation of test results into separate file

* Add magneta

* Cleaner verbose output

* Log partial results, so they can be dumped into file later for comparison

* Replace usage of internals of color.Colors

* Refactor how constants are hidden in Colors

* Add load/save test results into json

* Simple printer of multiple results

* result_data.compare() now takes formatter as argument which handles all printing

* result_data compare() code cleanup

* Missing closing bracket in get_cfg

* Test cases now correctly process stdin

* Add option to save log as json

* Move global variable input_dir into correct module

* Add missing suites for files compiled from sources

* Compile does not crash when tags are not being stubbed

* Fix passing stdin into Popen - input is bytes instead of str

* Some tests no longer print floats

* populate: Add color support

* run_tests: Multithread support

* run_tests: Introduces option to specify number of threads to use

* get_cfg: Introduces option to specify number of threads to use

* Update README with compile.py information

* Change --lib_dir to --runtime_lib to avoid llvm version problems

* WIP: Set default compiler to clang-8

* Logs are now stored inside batch_name_cfg/logs

* Fix bug in log file filename generation

* get_cfg: If all is specified as flavor, even empty tag files are selected

* Changed run_tests.py --libc_dir to --abi_lib_dir to match mcsema-lift naming conventions

* run_test: Timeout is now set to 5sec per test

* run_tests: timeout is static attribute of BaseTest.

* run_tests: Expand grep tests

* run_tests: timeout is now logged as type of test result

* src: Add test for global ctors/dtors.

* src: Compile script can now use user-defined compilators

* run: Add runners for global ctor/dtor tests.

* compile: TAGS can now be specified as first line in src file

* src: Add TAGS to source files

* compile: Source files can now contain more complex header

* compile: Config is now responsible for whole process

* src: reflect changes in compile script

* Missing copyright header

* Add util script

* populate: Reflect changes in tags structure

* get_cfg: Replace flavors by tags to be consistent

* get_cfg: Reflect changes in tags structure

* run: Parse configs

* run: Rework lift to use class instead of random stuff everywhere

* run: Removed unittest

* run: Remove tests.py

* src: Add headers to src tests

* run: Obliterate last remnants of tests.py

* Update README to reflect changes

* Change README from plaintext to markdown

* Update .remill_commit_id

* Update .remill_commit_id
This commit is contained in:
Aiethel
2019-10-27 23:54:22 +01:00
committed by Peter Goodman
parent 5c92db9895
commit d42db800a4
61 changed files with 3925 additions and 1 deletions
+1 -1
View File
@@ -1 +1 @@
9bddfa16afa6fea266c27b3538380ee17d75cb4b
3b9b36f4efbfe46ef82f1eaae8d117b3755878e0
+153
View File
@@ -0,0 +1,153 @@
New attempt to create a better test suite. In development process, use at your own peril.
# Use:
1) You can use `populate.py` to copy binaries to be tested from `/bin` or `/usr/bin`.
Directory that contains configs is iterated and each binary that has present at least one config file is searched for.
In case it is not found error is written on standard output, but the script continues with the rest.
Example:
```
./populate.py
> not_exists not found anywhere
> Found /bin/echo
> Found /bin/grep
```
2) In case you want to try your own sources you can use `compile.py` which compiles all sources from `src` directory. If option `--stub_tags` is used, the corresponding tag files are created.
3) First create a batch of cfg file using `get_cfg.py` -- you can select tags to run only subset of all tests (they are specified in `tags` directory).
+ tag all will get cfg for every file with at least one config present
+ there are several policies that allows modification of already existing batches
Example:
```
# Every file present in the `bin` directory will be lifted
# into cfg file.
# If a batch with name first_batch is present it will be deleted.
python get_cfg.py --disass dyninst --tags all
--batch first_batch --batch_policy D
# Lifts all missing files that have tags C.
# In case some file has already present cfg,
# it is not replaced
python get_cfg.py --disass dyninst --tags C
--batch first_batch --batch_policy C
# Updates all files with tag echo, leaves rest of the batch untouched
python get_cfg.py --disass dyninst --tags echo
--batch first_batch --batch_policy U
```
4) Once batch is created `run_tests.py` can be run.
# Config/Test files (tags/):
Directory tags (name to be changed) contains two types of files (beware, whitespaces are used as delimiters, therefore they matter):
1) `binary.kind.config`, which has following internal structure:
```
TAGS: one two ...
LIFT_OPTS: +one +two 87 !three
```
`TAGS` specify tags of this config, while `LIFT_OPTS` represent specific lift options. Options prefixed by `+` are added and prefix `!` means that the options is not used even though it would normally be by default.
One binary can have multiple config files.
At the moment each config should contain exactly one of the following two tags: `c`, `cpp`. They are later used to determine which compiler to use when recompiling.
2) `binary.test`, which has following internal structure:
```
TEST: cmd_option1 ...
STDIN: -Fpath/to/file/ or string
FILES: Not implemented yet
TEST: ...
...
```
For simple test cases it is easier to write this kind of test specification than the one used in python sources.
`STDIN:` after file is optional and so is `FILES:`. If value of `STDIN:` is prefixed by F corresponding file is loaded (it can be relative to the root of test dir) and used as stdin.
# src/
Files presented in `src` are meant to be compiled by `compile.py` and can have special header:
```
/* TAGS: ... */
/* CC_OPTS: ... */
/* LD_OPTS: ... */
/* LIFT_OPTS: kind1 ... */
/* LIFT_OPTS: kind2 ... */
...
/* TEST: */
/* STDIN: */
...
```
Everything except `CC_OPTS:` and `LD_OPTS:` is used to generated appropriate `.config/.test` files. `CC_OPTS:` and `LD_OPTS:` are forwarded to the compiler.
# Complex tests
Not every test can be described by simple "language" of the `.test` files, therefore it is needed to have a way to define those more complex ones.
In `run_tests.py` a global array `g_complex_test` is present, which is used to store more advanced configurations. It has following data type:
```
{ str : [ TestDetails ] }
```
The structure is rather intuitive -- each binary has one entry and can have multiple test cases stored in array of `TestDetails`. `TestDetails` currently have following options:
```
cmd (set in __init___): array of command line arguments
files: files that are used by the program
-> it is needed to copy them into appropriate location
check: files that are output of the program
-> it is needed to compare them
```
As usual, files can be specified by relative paths from root directory of tests.
# Directory structure:
```
get_cfg.py # script to create new cfg files
run_tests.py # runs the selected batches
populate.py # tries to copy binaries from `/bin` or `/usr/bin` based on tags files
bin
|- base_test
|- ... rest of tested binaries
tags
|- base_test.default.config
|- ... for each binary at least one config file
|- base.test
|- .. optional test files
# Folders containing cfg files (there may be a reason you want to have several,
# for example compare frontends or have cfgs of some special flavor)
batch1_cfg
|- base_test.cfg
|- ...
batch2_cfg
|- base_test.cfg
|- ...
# Symlinks to shared libraries used by original binaries
# Links themselves are created by get_cfg.py
shared_libs
|- libc.so
|- ...
# Inputs for the run_tests.py
inputs
|- input1.txt
|- program1
|- ...
```
+74
View File
@@ -0,0 +1,74 @@
# Copyright (c) 2019 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class Colors:
class c:
green = '\033[92m'
yellow = '\033[93m'
red = '\033[91m'
magneta = '\033[95m'
bg_yellow = '\033[43m'
orange = '\033[38;5;202m'
RESET = '\033[0m'
def get_result_color(total, success):
if total == 0:
return Colors.c.magneta
if total == success:
return Colors.c.green
if success == 0:
return Colors.c.red
return Colors.c.yellow
def get_bin_result(result):
if result == 1:
return Colors.c.green
if result == 0:
return Colors.c.red
return Colors.c.magneta
def clean():
return Colors.RESET
def c(color, message):
return color + message + clean()
def fail():
return Colors.c.red
def succ():
return Colors.c.green
#TODO: Not sure if it's worth to generate these for each color from attrs dynamically
def green(message):
return c(Colors.c.green, message)
def red(message):
return c(Colors.c.red, message)
def yellow(message):
return c(Colors.c.yellow, message)
def magneta(message):
return c(Colors.c.magneta, message)
def bg_yellow(message):
return c(Colors.c.bg_yellow, message)
def orange(message):
return c(Colors.c.orange, message)
def id(message):
return message
+176
View File
@@ -0,0 +1,176 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import os
import subprocess
tags_dir = "tags"
bin_dir = "bin"
src_dir = "src"
cxx_comp = 'clang++'
cc_comp = 'clang'
class Config:
allowed = ['TAGS', 'CC_OPTS', 'LD_OPTS', 'LIFT_OPTS', 'TEST']
def __init__(self, filename):
self.lift_opts = []
self.tests = []
self.cc_opts = []
self.ld_opts = []
self._parse_header(filename)
def _cc_opts(self, opts):
# Strip leading option specifier
self.cc_opts = opts[1:]
def _ld_opts(self, opts):
# Strip leading option specifier
self.ld_opts = opts[1:]
def _lift_opts(self, opts):
self.lift_opts.append((opts[1], opts[2:]))
def _tags(self, opts):
self.tags = opts[1:]
def _test(self, opts):
self.tests.append((opts[1:], None))
def _stdin(self, opts):
test, stdin = self.tests[-1]
if stdin is not None:
raise Exception("Two consecutive STDINs are not allowed")
self.tests[-1] = (test, ' '.join(opts[1:]))
def _parse_header(self, filename):
basename, ext = os.path.splitext(os.path.basename(filename))
self.name = basename
self.ext = ext
with open(filename, 'r') as src:
while 1:
line = src.readline()
line = line.rstrip('\n')
tokens = line.split(' ')
# Arrived at line that is not config information
if not tokens or (tokens[0] != '/*' or tokens[-1] != '*/'):
return
tokens = tokens[1:][:-1]
dispatch = {
'TAGS:' : Config._tags,
'CC_OPTS:' : Config._cc_opts,
'LD_OPTS:' : Config._ld_opts,
'LIFT_OPTS:' : Config._lift_opts,
'TEST:' : Config._test,
'STDIN:' : Config._stdin,
}
if tokens[0] not in dispatch:
raise Exception(tokens[0] + " is not allowed as entry header!")
dispatch[tokens[0]](self, tokens)
def create_config(self, name, opts, dst_dir):
with open(os.path.join(dst_dir, self.name + '.' + name + '.config'), 'w') as cfg:
cfg.write("TAGS: " + ' '.join(self.tags) + '\n')
cfg.write("LIFT_OPTS: " + ' '.join(opts) + '\n')
def create_test(self, dst_dir):
with open(os.path.join(dst_dir, self.name + '.test'), 'w') as test:
for case, stdin in self.tests:
test.write(' '.join(case) + '\n')
if stdin is not None:
test.write('STDIN: ' + stdin + '\n')
def create_configs(self, dst_dir):
if not self.lift_opts:
self.create_config('default', [''], dst_dir)
else:
for name, opts in self.lift_opts:
self.create_config(name, opts, dst_dir)
self.create_test(dst_dir)
def compile(self):
ext_map = { '.cpp' : cxx_comp,
'.c' : cc_comp }
cc = ext_map.get(self.ext, None)
if cc is None:
print(" > " + self.name + " has unknown extension")
return
out = os.path.join(bin_dir, self.name)
args = [cc, os.path.join(src_dir, self.name + self.ext), '-o', out] \
+ self.cc_opts + self.ld_opts
print(args)
pipes = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
std_out, std_err = pipes.communicate()
ret_code = pipes.returncode
if ret_code:
print("*** Compilation failed ***")
print("\n** stdout:")
print(std_out)
print("\n** stderr:")
print(std_err)
def main():
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
'--stub_tags',
help='Create tag files with corresponding tags, possibly empty',
required=False,
nargs='*')
arg_parser.add_argument(
'--cxx',
help='Path to C++ compiler to use',
required=False)
arg_parser.add_argument(
'--cc',
help='Path to C compiler to use',
required=False)
args, extra_args = arg_parser.parse_known_args()
if args.cc is not None:
global cc_comp
cc_comp = args.cc
if args.cxx is not None:
global cxx_comp
cxx_comp = args.cxx
# If `bin` does not exist create it first
if not os.path.isdir(bin_dir):
os.mkdir(bin_dir)
for f in os.listdir(src_dir):
c = Config(os.path.join(src_dir, f))
if args.stub_tags is not None:
c.tags += args.stub_tags
c.create_configs('tags')
c.compile()
if __name__ == '__main__':
main()
+372
View File
@@ -0,0 +1,372 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import operator
import os
import queue
import threading
import shutil
import sys
import subprocess
import tempfile
from shlex import quote
import colors
import util
tags_dir="tags"
so_dir="shared_libs"
bin_dir="bin"
ALL_TAG="all"
FAIL = 0
SUCCESS = 1
IGNORED = 2
MESSAGES = { FAIL: "Fail", SUCCESS: "Success", IGNORED: "Skipped" }
INDENT = 2
log_dir_name = "logs"
def make_dir(path):
print(" > Creating directory: " + path)
try:
os.makedirs(path)
except:
print("[Error] could not create directory " + path)
def is_batch_dir_sane(batch_name):
for filename in os.listdir(batch_name):
name, extension = os.path.splitext(filename)
fullname = os.path.join(batch_name, filename)
if ((os.path.isfile(fullname) and extension != ".cfg") or \
(os.path.isdir(fullname) and filename != log_dir_name)):
return False
return True
def is_valid_binary(binary_name):
bin_path = os.path.join(bin_dir, binary_name)
return os.path.isfile(bin_path)
# Return (list of filtered names, number of files that are missing)
def get_binaries_from_tags(desired):
binaries = []
missing = 0
# We want to get cfg for everything
get_all = ALL_TAG in desired
bin2tag = util.get_bin2tags(tags_dir)
for binary, tags in bin2tag.items():
if get_all or any(x in desired for x in tags):
if not is_valid_binary(binary):
print(colors.bg_yellow(
" > Skipping " + binary+ " : file missing"))
missing = missing + 1
else:
print(" > Selecting " + binary)
binaries.append(binary)
return (binaries, missing)
def create_batch_dir(batch, policy):
batch_name = batch + "_cfg"
if batch_name not in os.listdir():
print(" > Batch name is unique")
make_dir(batch_name)
make_dir(os.path.join(batch_name, log_dir_name))
return batch_name
print(" > Batch with same name already exists")
print(" > Selected policy is " + policy)
if policy == "D":
print(" > Removing old batch")
if is_batch_dir_sane(batch_name):
shutil.rmtree(batch_name)
make_dir(batch_name)
make_dir(os.path.join(batch_name, log_dir_name))
else:
print(" > Batch folder is not sane, remove manually")
sys.exit(1)
return batch_name
# From lift_program.py
def binary_libraries(binary):
try:
res = subprocess.check_output(['ldd', binary]).decode()
except:
print(" \t[W] ldd failed for " + binary)
return
for line in res.split("\n"):
if "=>" not in line:
continue
name, path_and_addr = line.split(" => ")
path_and_addr = path_and_addr.strip(" ")
if not path_and_addr.startswith("/"):
continue
lib = " ".join(path_and_addr.split(" ")[:-1])
lib = os.path.realpath(lib)
if os.path.isfile(lib):
yield name.strip(), lib
def update_shared_libraries(binary):
if not os.path.isdir(so_dir):
print(" > Creating " + so_dir)
os.mkdir(so_dir)
for name, path in binary_libraries(binary):
if name in os.listdir(so_dir):
continue
sym_name = os.path.join(so_dir, name)
try:
print(" \t> " + sym_name + " => " + path)
os.symlink(path, sym_name)
except:
pass
# From lift_program.py
# Most likely there will be only x86-64 binaries for the time being,
# but it won't hurt to have it in place once we decide to add another tests
def binary_info(binary):
res = subprocess.check_output(['file', binary]).decode()
is_pie = 'LSB shared object' in res or 'Mach-O 64' in res or 'LSB pie executable' in res
address_size = 64
if 'aarch64' in res:
arch = 'aarch64'
elif 'x86-64' in res or 'x86_64' in res:
arch = 'amd64_avx'
elif 'x86' in res:
arch = 'x86_avx'
address_size = 32
else:
raise Exception("Unknown architecture for file type {}".format(res))
return address_size, arch, is_pie
def dyninst_frontend(binary, cfg, args, log_file):
address_size, arch, is_pie = binary_info(binary)
disass_args = [
"mcsema-dyninst-disass",
"--arch", arch,
# TODO: Portability
"--os", "linux",
"--binary", quote(binary),
"--output", quote(cfg),
"--entrypoint", "main",
"--std_defs", args.std_defs ]
if is_pie:
disass_args.append("--pie_mode")
# TODO: May not be needed
disass_args.append("true")
# TODO: This is too verbose for normal output
#print(" \t> " + " ".join(disass_args))
ret = subprocess.call(disass_args)
if ret:
return FAIL
return SUCCESS
# TODO: Testing REQUIRED
def ida_frontend(binary, cfg, args, log_file):
address_size, arch, is_pie = binary_info(binary)
disass_args = [
'mcsema-disass',
'--arch', arch,
'--os', 'linux',
'--binary', quote(binary),
'--output', quote(cfg),
'--entrypoint', 'main',
'--log_file', log_file,
'--disassembler', args.path_to_disass]
if is_pie:
disass_args.append("--pie_mode")
print(" \t> " + " ".join(disass_args))
ret = subprocess.call(disass_args)
if ret:
return FAIL
return SUCCESS
def binja_frontend(binary, cfg, args, log_file):
print(" > Not implemented")
sys.exit(1)
# TODO: We may want for each file to be lifted in separate directory and on a copy
# (in the case frontend is broken and modifies the original itself)
def get_cfg(*t_args, **kwargs):
todo, args, lifter, result = t_args
while not todo.empty():
try:
binary, cfg = todo.get()
except queue.Empty:
return
bin_path = os.path.join(bin_dir, binary)
print("\n > Processing " + bin_path)
update_shared_libraries(bin_path)
log_file = os.path.join(args.batch + "_cfg", log_dir_name, binary + ".log")
result[binary] = lifter(bin_path, cfg, args, log_file)
# TODO: Handle other frontends
def get_lifter(disass):
if disass == "dyninst":
return dyninst_frontend
if disass == "ida":
return ida_frontend
print(" > Support for chosen frontend was not implemented yet!")
sys.exit(1)
def print_result(result, missing):
print("\nResults:")
stat = dict()
for key, val in sorted(result.items(), key=operator.itemgetter(0)):
print(key.ljust(30).rjust(30 + INDENT) + colors.get_bin_result(val) +
(MESSAGES[val]).rjust(5) + colors.clean())
if val in stat:
stat[val] += 1
else:
stat[val] = 1
print("\nTotal:")
for key, val in MESSAGES.items():
print(val)
if key not in stat:
print(" " * INDENT, str(0))
else:
print(" " * INDENT, stat[key])
print("\nMissing:")
print(" " * INDENT, missing)
def main():
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
"--disass",
help='Frontend tobe used: ida | binja | dyninst',
choices=["ida", "binja", "dyninst"],
required=True)
arg_parser.add_argument(
"--path_to_disass",
help="Path to disassembler, needed in case ida is chosen as frontend",
default=None,
required=False)
arg_parser.add_argument(
"--tags",
help="Flavors to be lifted",
nargs="+",
required=True)
arg_parser.add_argument(
"--dry_run",
help="Should actual commands be executed?",
default=False,
required=False)
arg_parser.add_argument(
"--batch",
help="Specify batch name",
required=True)
arg_parser.add_argument(
"--batch_policy",
choices=["D", "U", "C"],
help="How to resolve already existing batch\n D: delete all old cfgs\nU: Update all\nC: create only missing",
default="D",
required=False)
arg_parser.add_argument(
"--std_defs",
help="In case frontend still supports/needs it, can be found with McSema sources",
default="../../tools/mcsema_disass/defs/linux.txt",
required=False)
arg_parser.add_argument(
'--jobs',
help = "Number of threads to use",
default = 1,
required = False)
args, command_args = arg_parser.parse_known_args()
if args.disass == "ida":
if args.path_to_disass is None:
print("IDA frontend is selected but --path_to_disass is not")
sys.exit(1)
if not os.path.isfile(args.path_to_disass):
print("IDA frontend is selected but --path_to_disass is not a file")
sys.exit(1)
print("Checking batch name")
batch_dir = create_batch_dir(args.batch, args.batch_policy)
print("Select all binaries, specified by tags")
binaries, missing = get_binaries_from_tags(args.tags)
result = dict()
print("\nIterating over binaries")
todo = queue.Queue()
for b in binaries:
cfg = os.path.join(batch_dir, b + ".cfg")
if args.batch_policy == "C" and os.path.isfile(cfg):
print(" \t> " + cfg + " is already present, not updating")
result[b] = IGNORED
else:
todo.put((b, cfg))
threads = []
for i in range(int(args.jobs)):
t = threading.Thread(
target=get_cfg, args=(todo, args, get_lifter(args.disass), result))
t.start()
threads.append(t)
for t in threads:
t.join()
print_result(result, missing)
return 0
if __name__ == '__main__':
main()
@@ -0,0 +1,7 @@
+ 8 5
+ 98 -8
+ -6 -6
- -5 -8
! 5
m 58 8
q
@@ -0,0 +1,17 @@
* 9 8
- 9 8
* 9 -8
p 75
p 9
p 7
a 5
1
2
3
4
5
s 3
1
-1
0
q
@@ -0,0 +1,6 @@
c 8 7
+ 8 9
! 5
d 5 -6
/ 5 4
q
@@ -0,0 +1,10 @@
p 78
p 5
p 35
p 57
p 89
p 51
p 4
p 89
p 15896
q
+5
View File
@@ -0,0 +1,5 @@
What a beauty!
int main() {
return 0;
}
Cras cras, semper cras sic evadit eatas.
Binary file not shown.
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import shutil
import stat
import colors
import util
tags_dir = "tags"
bin_dir = "bin"
def try_find(locations, basename):
for p in locations:
maybe = os.path.join(p, basename)
if os.path.isfile(maybe):
print(" > " + colors.green("Found " + maybe))
new_file = os.path.join(bin_dir, basename)
shutil.copyfile(maybe, new_file)
st = os.stat(new_file)
os.chmod(new_file, st.st_mode | stat.S_IEXEC)
return True
return False
def main():
# TODO: Make it portable
locations = [ "/usr/bin", "/bin"]
current = set()
# If `bin` does not exist create it first
if not os.path.isdir(bin_dir):
os.mkdir(bin_dir)
for f in os.listdir(bin_dir):
current.add(f)
for f in os.listdir(tags_dir):
basename = util.strip_whole_config(f)
if not basename:
continue
if basename in current:
print(" > " + basename + " is present in " + tags_dir)
continue
if not try_find(locations, basename):
print(" > " + colors.red(basename + " not found anywhere"))
if __name__ == '__main__':
main()
+182
View File
@@ -0,0 +1,182 @@
import json
import operator
import os
import colors
UNKNOWN = 0
RUN = 1
FAIL = 2
ERROR = 3
TIMEOUT = 4
_color_mapping = {
RUN : colors.green,
FAIL: colors.orange,
ERROR : colors.red,
TIMEOUT: colors.magneta,
UNKNOWN : colors.id,
}
class TCData:
def __init__(self, basename = None, bin_p = None, recompiled_p = None):
self.binary = bin_p
self.recompiled = recompiled_p
self.basename = basename
self.total = 0
self.success = 0
self.cases = {}
self.ces = {}
def is_recompiled(self):
return self.recompiled is not None
def get_result_color(self):
if self.total == 0:
return colors.magneta
if self.total == self.success:
return colors.green
if self.success == 0:
return colors.red
return colors.orange
def print(self, verbosity):
end = "\n"
if verbosity == 0:
end = " "
print("{:<30s}".format(self.get_result_color()(self.basename)), end=end)
if not self.is_recompiled():
print("\tRecompilation failed: ERROR")
return
if self.total == 0:
print(colors.magneta("\tNo tests were executed"))
return
if verbosity == 0:
print(colors.get_result_color(self.total, self.success) +
"{:>5s}".format(str(self.success) + "/" + str(self.total)) +
colors.clean())
elif verbosity == 1:
for case, val in sorted(self.cases.items(), key = operator.itemgetter(0)):
print(" " * 2, _color_mapping[val](case))
def print_ces(self):
for case, ce in self.ces.items():
print(colors.red(self.basename) + ': '+ ('without_args' if not case else case))
print(ce)
def get(self, test_case):
return self.cases.get(test_case, UNKNOWN)
def outer_get(self, name, test_case):
if self and name == self.basename:
return self.get(test_case)
return UNKNOWN
class _MyEncoder(json.JSONEncoder):
def default(self, o):
return o.__dict__
def _object_hook(d):
if "binary" in d:
obj = TCData()
obj.__dict__.update(d)
return obj
return d
# SQL serialization may be useful as well
def store_json(root, filename):
if os.path.isfile(filename):
print("Log file already exists")
return
with open(filename, 'w') as f:
json.dump(root, f, cls=_MyEncoder, indent=4)
def load_json(filename):
with open(filename, 'r') as f:
return json.load(f, object_hook = _object_hook)
class _Format:
l_header = 25
def header(self, message):
self._header = message
self.h_queued = True
def case(self, message):
self._case = message
def _header_dump(self):
if not self.h_queued:
return
self.h_queued = False
printed = self._header.ljust(_Format.l_header)
self.h_fill = len(printed)
print(printed, end="")
self.present_header = True
def _case_dump(self):
fill = 0 if self.present_header else self.h_fill
printed = " " * fill + "|" + self._case.ljust(_Format.l_header) + "|"
print(printed, end="")
self.present_header = False
def _res_dump(self, result):
print(" " + str(result) + " |", end="")
# TODO: Print something else than numbers with verbosity = 2
def dump(self, results, verbosity, original):
# Print everything and really verbose
if verbosity == 2:
self._header_dump()
self._case_dump()
self._res_dump(original)
for r in results:
print(" ", _color_mapping[r](str(r)), " |", end="")
print()
if verbosity == 0:
if all(r == original for r in results):
return
self._header_dump()
self._case_dump()
self._res_dump(original)
for r in results:
if r == original:
print(" " * 3 + "|", end="")
else:
print(" ", _color_mapping[r](str(r)), " |", end="")
print()
# Compare test results to some base and print them in reasonable way
# f is formatter -> first suite name and then case are preset and when dump() is called
# actual results are printed based on verbosity level
def compare(base, results, formatter, full):
# first we need to sort the items
s_base = sorted(base.items(), key=operator.itemgetter(0))
for entry in s_base:
suite_name, tcdata = entry
formatter.header(suite_name)
for case_name, case_result in tcdata.cases.items():
formatter.case(case_name)
r_case_results = []
for r in results:
r_tcdata = r.get(suite_name, None)
r_case_results.append(r_tcdata.outer_get(tcdata.basename, case_name))
formatter.dump(r_case_results, full, case_result)
+632
View File
@@ -0,0 +1,632 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import difflib
import filecmp
import operator
import os
import queue
import threading
import shutil
import subprocess
from subprocess import CalledProcessError
import sys
import tempfile
import unittest
import colors
import result_data
import util
llvm_version = 8
lift = None
bin_dir = "bin"
libmcsema = None
recompiled_dir = "recompiled"
tags_dir = 'tags'
batches = []
shared_libs = None
abi_lib_dir = None
def get_recompiled_name(name):
return name
# Print results of tests
def print_results(t_cases):
for key, val in sorted(t_cases.items(), key = operator.itemgetter(0)):
val.print(0)
for key, val in sorted(t_cases.items(), key = operator.itemgetter(0)):
val.print_ces()
def log_results(result, into):
for entry in result.failures:
what = entry[0]
into[what.name].cases[what._testMethodName] = result_data.FAIL
for entry in result.errors:
what = entry[0]
# Do not overwrite timeouts
if into[what.name].cases[what._testMethodName] != result_data.TIMEOUT:
into[what.name].cases[what._testMethodName] = result_data.ERROR
# Fill global variables
# TODO: Rework, this is really ugly
def check_arguments(args):
if not os.path.isfile(args.lift):
print("{} passed to --lift is not a valid file".format(args.lift))
sys.exit (1)
global lift
lift = args.lift
if not os.path.isfile(args.runtime_lib):
print ("{} passed to --runtime_lib is not a valid file".format(args.runtime_lib))
sys.exit (1)
global libmcsema
libmcsema = args.runtime_lib
if not os.path.isdir(args.bin_dir):
print("{} passed to --bin_dir is not a valid directory".format(args.bin_dir))
sys.exit (1)
bin_dir = os.path.abspath(args.bin_dir)
if not os.path.isdir(args.shared_lib_dir):
print("{} passed to --shared_lib_dir is not a valid directory".format(args.shared_lib_dir))
sys.exit (1)
global shared_libs
shared_libs = []
for lib_name in os.listdir(args.shared_lib_dir):
shared_libs.append(os.path.join(args.shared_lib_dir, lib_name ))
print("\n > Shared libraries: ")
print(shared_libs)
if not os.path.isdir(args.abi_lib_dir):
print ("{} passed to --abi_lib_dir is not a valid directory".format(args.abi_lib_dir))
sys.exit (1)
global abi_lib_dir
abi_lib_dir = ''
for lib_name in os.listdir(args.abi_lib_dir):
if lib_name.endswith(".bc"):
abi_lib_dir += os.path.join(args.abi_lib_dir, lib_name + ',')
print("\n > --abi_libraries files:")
print(abi_lib_dir)
# TODO: This whole snippet can be done using argparser and some actions
if args.batch is not None:
for batch in args.batch:
batch_dir = batch + "_cfg"
if not os.path.isdir(batch_dir):
print("{} passed to --batch is not a valid directory".format(batch))
sys.exit(1)
batches.append(batch_dir)
if args.batch_dir is not None:
for batch in args.batch_dir:
if not os.path.isdir(batch):
print("{} passed to --batch_dir is not a valid directory".format(batch))
sys.exit(1)
batches.append(batch_dir)
if not batches:
print("No batch is selected, exiting")
sys.exit(0)
print(batches)
def exec_and_log_fail(args):
pipes = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
std_out, std_err = pipes.communicate()
ret_code = pipes.returncode
if ret_code:
print("** stdout:")
print(std_out)
print("** stderr:")
print(std_err)
return False
return True
class Config:
class Result:
SUCCESS = 0
LIFT_FAIL = 1
RECOMPILE_FAIL = 2
defaults = [ '-os', 'linux', '-arch', 'amd64' ]
togglable = {
'abi_libraries' : ['-abi_libraries', abi_lib_dir],
}
# Since strings are immutable, hotfix is needed once abi_lib_dir is set
def _fix_excludes(self):
flag, opt = self.togglable['abi_libraries']
self.togglable['abi_libraries'] = (flag, abi_lib_dir)
def __init__(self, name, src, cfg_path):
self.name = name
self.binary = os.path.join(bin_dir, name)
self.config = src.rsplit('.', 2)[1]
self.id = self.name + '.' + self.config
self.cfg = cfg_path
self.lift_args = []
self.exclude_args = []
self.tags = []
self._fix_excludes()
self._parse_config(src)
def _tags(self, line):
self.tags = line.split(' ')[1:]
def _lift_opts(self, line):
tokens = line.split(' ')[1:]
# LIFT_OPTS are empty
if not tokens:
return
exclude = []
for opt in tokens:
if not opt:
break
elif opt[0] == '+':
self.lift_args.append(opt[1:])
elif opt[0] != '!':
self.lift_args.append(opt)
else:
exclude.append(opt[1:])
for key, val in Config.togglable.items():
if key in exclude:
continue
self.lift_args += val
def _parse_config(self, src):
print(' > Parsing', src)
with open(os.path.join(tags_dir, src), 'r') as cfg:
for line in cfg:
line = line.rstrip('\n')
header = line.split(' ', 1)[0]
header_dispatch = {
'TAGS:' : Config._tags,
'LIFT_OPTS:' : Config._lift_opts,
}
if header not in header_dispatch:
raise Exception("Unknown header {}".format(header))
header_dispatch[header](self, line)
def lift(self, test_dir):
print(" > Lifting", self.name + self.config)
self.bc = os.path.join(test_dir, '.'.join([self.name, self.config, 'bc']))
self.recompiled = os.path.join(test_dir, self.name + '.' + self.config)
args = [lift] + self.defaults + self.lift_args + \
['-output', self.bc, '-cfg', self.cfg]
print(args)
if not exec_and_log_fail(args):
return Config.Result.LIFT_FAIL
return self.recompile()
def recompile(self):
compiler = None
if 'c' in self.tags:
compiler = "clang-{}"
elif 'cpp' in self.tags:
compiler = "clang++-{}"
else:
print(" > Cannot decide on compiler when recompiling",\
self.name + '.' + self.config)
return Config.Result.RECOMPILE_FAIL
compiler = compiler.format(llvm_version)
args = [compiler, self.bc, '-o', self.recompiled, \
libmcsema, '-lpthread', '-lm', '-ldl'] + shared_libs
if not exec_and_log_fail(args):
return Config.Result.RECOMPILE_FAIL
return Config.Result.SUCCESS
def parallel_lift(*t_args):
todo, test_dir, results = t_args
while not todo.empty():
try:
config = todo.get()
except queue.Empty:
return
res = config.lift(test_dir)
# TODO: More fine grained log
if res != Config.Result.SUCCESS:
results[self.id] = result_data.TCData(self.id, self.recompiled, self.binary)
def get_configs(directory, allowed_tags, batched):
result = []
for f in os.listdir(directory):
name = util.strip_whole_config(f)
if not name or name not in batched:
continue
c = Config(name, f, batched[name])
if allowed_tags is None:
result.append(c)
elif any(x in allowed_tags for x in c.tags):
result.append(c)
return result
class TestDetails:
def __init__(self, cmd):
self.cmd = cmd
self.files = None
self.stdin = None
self.f_stdin = None
self.check = []
def set_files(self, files):
self.files = files
return self
def set_check(self, check):
self.check = check
return self
def set_f_stdin(self, f_stdin):
self.f_stdin = f_stdin
return self
def set_stdin(self, stdin):
self.stdin = stdin
return self
def files(self, files):
if self.files is not None:
raise Exception("Incorrect format of test case")
self.files = files
def stdin(self, stdin):
if stdin[0] != 'F':
self.stdin = stdin.encode()
return
self.f_stdin = os.path.abspath(stdin[1:])
class TestCase:
def __init__(self, src=None):
self.details = []
if src is not None:
self._parse(src)
def _parse(self, src):
dispatch = {
'STDIN:' : TestDetails.stdin,
'FILES:' : TestDetails.files,
}
with open(src, 'r') as f:
for line in f:
line = line.rstrip('\n')
head = line.split(' ', 1)[0]
if head in dispatch:
dispatch[head](self.details[-1], line.split(' ', 1)[1])
else:
self.details.append(TestDetails(line.split(' ')))
# .test was present but empty
if not self.details:
self.details.append(TestDetails(['']))
class Runner:
def __init__(self, config, test_case):
self.config = config
self.test_case = test_case
def set_up(self):
self.t_bin = tempfile.mkdtemp(dir=os.getcwd(), prefix='bin_t')
self.t_recompiled = tempfile.mkdtemp(dir=os.getcwd(), prefix='recompiled_t')
self.sawed_cwd = os.getcwd()
cfg = self.config
os.symlink(os.path.abspath(cfg.binary), os.path.join(self.t_bin, cfg.name))
os.symlink(cfg.recompiled, os.path.join(self.t_recompiled, cfg.name))
def tear_down(self):
os.chdir(self.sawed_cwd)
shutil.rmtree(self.t_recompiled)
shutil.rmtree(self.t_bin)
def copy_files(self, detail):
if detail.files is not None:
for f in detail.files:
basename = os.path.basename(f)
full_name = f
r = os.path.join(self.t_recompiled, basename)
b = os.path.join(self.t_bin, basename)
shutil.copyfile(full_name, r)
shutil.copyfile(full_name, b)
def compare(self, expected, actual, files):
e_out, e_err, e_ret = expected
a_out, a_err, a_ret = actual
correct = True
counterexample = ''
# TODO: This cannot be more hacky than this
try:
if a_out != e_out:
counterexample += 'stdout:\n'
counterexample += '\tExpected:\n'
counterexample += e_out.decode() + '\n'
counterexample += '\tGot:\n'
counterexample += a_out.decode() + '\n'
correct = correct and False
if a_err != e_err:
counterexample += 'stderr:'+ '\n'
counterexample += '\tExpected:'+ '\n'
counterexample += e_err.decode()+ '\n'
counterexample += '\tGot:'+ '\n'
counterexample += a_err.decode()+ '\n'
correct = correct and False
except UnicodeDecodeError as e:
correct = False
counterexample += str(e) + '\n'
if e_ret != e_ret:
counterexample += "Return code: " + str(e_ret) + ' != ' + str(a_ret) + '\n'
correct = correct and False
for name in files:
base_name = os.path.basename(name)
actual = os.path.join(self.t_recompiled, base_name)
expected = os.path.join(self.t_bin, base_name)
if not filecmp.cmp(expected, actual):
counterexample += 'Files do not match: ' + basename + '\n'
correct = correct and False
result = result_data.RUN if correct else result_data.FAIL
return (result, counterexample)
def open_stdin(self, t_dir, args, stdin):
with open(stdin, 'rb') as f:
r = f.read()
return self.exec_(t_dir, args, r)
def exec_(self, t_dir, args, stdin):
os.chdir(t_dir)
try:
pipes = subprocess.Popen(
args, stdout=subprocess.PIPE,
stderr = subprocess.PIPE,
stdin = subprocess.PIPE)
out, err = pipes.communicate(stdin, timeout=5)
ret = pipes.returncode
os.chdir(self.sawed_cwd)
return (out, err, ret)
except subprocess.TimeoutExpired as e:
pipes.terminate()
raise e
def exec(self, detail, files):
# To avoid calling system-wide installed binaries
filename = './' + self.config.name
_exec = Runner.exec_ if detail.f_stdin is None else Runner.open_stdin
stdin = detail.f_stdin if detail.f_stdin is not None else detail.stdin
try:
print(detail.cmd)
expected = _exec(self, self.t_bin, [filename] + detail.cmd, stdin)
actual = _exec(self, self.t_recompiled, [filename] + detail.cmd, stdin)
return self.compare(expected, actual, files)
except subprocess.TimeoutExpired as e:
return result_data.TIMEOUT
def run(self, detail):
self.set_up()
self.copy_files(detail)
result, ce = self.exec(detail, detail.check)
self.tear_down()
return (result, ce)
def evaluate(self, results):
c = self.config
results[c.id] = result_data.TCData(c.id, c.recompiled, c.binary)
for tc in self.test_case:
for d in tc.details:
result, ce = self.run(d)
results[c.id].cases[' '.join(d.cmd)] = result
results[c.id].total += 1
if result == result_data.RUN:
results[c.id].success += 1
else:
results[c.id].ces[' '.join(d.cmd)] = ce
class Tester:
def __init__(self, configs, test_def_dir):
# Config -> TestCase
self.cases = {}
for c in configs:
self.cases[c] = []
for f in os.listdir(test_def_dir):
basename, ext = os.path.splitext(f)
if ext != '.test':
continue
tc = TestCase(os.path.join(test_def_dir, f))
for key, val in self.cases.items():
if key.name == basename:
val.append(tc)
for key, val in g_complex_test.items():
for k, v in self.cases.items():
if k.name == key:
tc = TestCase()
tc.details = val
v.append(tc)
def run(self, results):
for key, val in self.cases.items():
print(key.id, 'number of tests:', len(val))
r = Runner(key, val)
r.evaluate(results)
g_complex_test = {
"gzip" :
[
TestDetails(['--help']),
TestDetails(['--version']),
TestDetails(['-asda']),
TestDetails(['-f', './data.txt']).set_files(['inputs/data.txt']). \
set_check(['data.txt.gz']),
TestDetails(['-l', './dec_data.txt.gz']).set_files(['inputs/dec_data.txt.gz']),
TestDetails(['-df', './dec_data.txt.gz']).set_files(['inputs/dec_data.txt.gz']).\
set_check(['dec_data.txt']),
],
"cat":
[
TestDetails(['--help']),
TestDetails(['--version']),
TestDetails(['data.txt']).set_files(['inputs/data.txt']),
TestDetails(['-n', 'data.txt']).set_files(['inputs/data.txt']),
],
"echo":
[
TestDetails(['--help']),
TestDetails(['--version']),
TestDetails(['Hello Wordl!']),
],
}
# Right now batches are combined, maybe it would make sense to separate batches from each other
# that can be useful when comparing performance of frontends
def main():
arg_parser = argparse.ArgumentParser(
formatter_class = argparse.RawDescriptionHelpFormatter)
arg_parser.add_argument('--lift',
help = "Path to the mcsema-lift binary",
required = True)
arg_parser.add_argument('--runtime_lib',
help = "Runtime library for lifted bitcode \
(e.g. libmcsema-rt64-6.0.a",
required = True)
arg_parser.add_argument('--shared_lib_dir',
help = "Directory that contains shared libraries used by original binaries",
default = "shared_libs",
required = False)
arg_parser.add_argument('--bin_dir',
help = "Directory that contains original binaries",
default = "bin",
required = False)
arg_parser.add_argument('--batch',
help = "Batch names",
nargs = '+',
required = False)
arg_parser.add_argument('--batch_dir',
help = 'Directories with cfgs',
nargs = '+',
required = False)
arg_parser.add_argument('--abi_lib_dir',
help = "Directory that contains bitcode types of external functions",
required = True)
arg_parser.add_argument('--dry_run',
help = 'Do not run any tests',
required = False)
arg_parser.add_argument('--save_log',
help = "Name of file to save result in json format",
required = False)
arg_parser.add_argument('--jobs',
help = "Number of threads to use",
default = 1,
required = False)
arg_parser.add_argument('--tags',
help = "Test only these tags from batch",
required = False)
args, command_args = arg_parser.parse_known_args()
check_arguments(args)
# Create directory to store recompiled binaries
# TemporaryDirectory() is not used, since we may want to have a look at recompiled
# code, maybe we want some --preserve option
test_dir = tempfile.mkdtemp(dir=os.getcwd())
# basename -> path
batched = {}
for batch in batches:
for f in os.listdir(batch):
if os.path.isfile(os.path.join(batch, f)):
basename, ext = os.path.splitext(f)
batched[basename] = os.path.join(batch, f)
configs = get_configs(tags_dir, args.tags, batched)
_todo = queue.Queue()
for c in configs:
_todo.put(c)
threads = []
results = {}
for i in range(int(args.jobs)):
t = threading.Thread(target=parallel_lift, args=(_todo, test_dir, results))
t.start()
threads.append(t)
for t in threads:
t.join()
Tester(configs, tags_dir).run(results)
print_results(results)
return
if __name__ == '__main__':
main()
@@ -0,0 +1,44 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **args)
{
uint8_t fold = 0xAF;
void (*obf_funcs[]) (void) = {
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
(void (*) (void))main,
};
printf("hrm: %zu\n", sizeof (obf_funcs));
printf("hrm: %zu\n", sizeof (void *));
printf("div: %zu\n", (sizeof (obf_funcs) / sizeof (void *)));
fold %= (sizeof (obf_funcs) / sizeof (void *));
printf("so answer: %d\n", fold);
return 0;
}
+37
View File
@@ -0,0 +1,37 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unistd.h>
#include <stdlib.h>
static char someglobal = 1;
int writeit()
{
write(2,&someglobal,1);
someglobal++;
write(2,&someglobal,1);
return 0;
}
int main(void)
{
someglobal = 0x68;
writeit();
return 0;
}
@@ -0,0 +1,23 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main(int argc, const char *argv[]) {
printf("%s: %s\n", "partial string test", "string test");
return 0;
}
+93
View File
@@ -0,0 +1,93 @@
/* TAGS: min c */
/* TEST: 12 */
/* TEST: 15 */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[]) {
if(argc < 2) {
return -1;
}
int input = atoi(argv[1]);
switch(input) {
case 0:
printf("Input was zero\n");
break;
case 1:
printf("Input was one\n");
break;
case 2:
printf("Input was two\n");
break;
case 4:
printf("Input was four\n");
break;
case 6:
printf("Input was six\n");
break;
case 12:
printf("Input was twelve\n");
break;
case 13:
printf("Input was thirteen\n");
break;
case 19:
printf("Input was nineteen\n");
break;
case 255:
printf("Input was two hundred fifty-five\n");
break;
case 0x12389:
printf("Really big input: 0x12389\n");
break;
case 0x1238A:
printf("Really big input: 0x1238A\n");
break;
case 0x1238B:
printf("Really big input: 0x1238B\n");
break;
case 0x1238C:
printf("Really big input: 0x1238C\n");
break;
case 0x1238D:
printf("Really big input: 0x1238D\n");
break;
case 0x1238F:
printf("Really big input: 0x1238F\n");
break;
case 0x12390:
printf("Really big input: 0x12390\n");
break;
case 0x12391:
printf("Really big input: 0x12391\n");
break;
case 0x12392:
printf("Really big input: 0x12392\n");
break;
case 0x12393:
printf("Really big input: 0x12393\n");
break;
default:
printf("Unknown input: %d\n", input);
}
return 0;
}
+34
View File
@@ -0,0 +1,34 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main (void)
{
int array [10];
int sum = 0;
for (int i = 0; i < 10; ++i)
array [i] = 2 * i;
for (int i = 0; i < 10; ++i)
sum += array [i];
printf ("Result: %d\n", sum);
return 0;
}
+73
View File
@@ -0,0 +1,73 @@
/* TAGS: min c */
/* TEST: 12 */
/* TEST: 14 */
/* TEST: 0 */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
void bubbleSort (int a [], int array_size)
{
int i, j, temp;
for (i = 0; i < array_size - 1; ++i)
{
for (j = 0; j < array_size - 1 - i; ++j)
{
if (a [j] > a [j+1])
{
temp = a [j+1];
a [j+1] = a [j];
a [j] = temp;
}
}
}
}
int main (int argc, char **argv)
{
if (argc < 2)
return 1;
int size = atoi (argv [1]);
int i = 0;
int array [size];
for (int i = 0; i < size; ++i)
array [i] = size - i;
printf ("Before sorting the list is: \n");
for(i = 0; i < size; ++i)
{
printf ("%d ", array [i]);
}
bubbleSort (array, size);
printf ("\nAfter sorting the list is: \n");
for(i = 0; i < size; ++i)
{
printf ("%d ", array [i]);
}
printf("\n");
return 0;
}
+232
View File
@@ -0,0 +1,232 @@
/* TAGS: min c */
/* TEST: */
/* STDIN: Finputs/calc_input1.txt */
/* TEST: */
/* STDIN: Finputs/calc_input2.txt */
/* TEST: */
/* STDIN: Finputs/calc_input3.txt */
/* TEST: */
/* STDIN: Finputs/calc_input4.txt */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int sum();
int difference();
float divideFloat();
int divideInt();
int modulo();
int times();
long power();
long long int factorial();
int sums();
float average();
long long int binomialCoeficient();
int is_prime();
long long int factorialWithArgument(int a);
void cleanInput();
int main(void) {
char c;
do {
printf("> ");
c = getchar();
switch (c) {
case '+':
printf("# sum\n");
printf("# %i\n", sum());
break;
case '-':
printf("# difference\n");
printf("# %i\n", difference());
break;
case '/':
printf("# %.2f\n", divideFloat());
break;
case 'd':
printf("# %i\n", divideInt());
break;
case 'm':
printf("# %i\n", modulo());
break;
case '*':
printf("# %i\n", times());
break;
case '^':
printf("# %li\n", power());
break;
case '!':
printf("# %lli\n", factorial());
break;
case 's':
printf("# %i\n", sums());
break;
case 'a':
printf("# %.2f\n", average());
break;
case 'c':
printf("# %lli\n", binomialCoeficient());
break;
case 'p':
if (is_prime()) {
printf("# y\n");
} else {
printf("# n\n");
}
break;
default:
break;
}
cleanInput();
} while (c != 'q');
return 0;
}
void cleanInput() {
while (getchar() != '\n')
;
}
int sum() {
int a, b;
scanf(" %i %i", &a, &b);
return (a + b);
}
int difference() {
int a, b;
scanf(" %i %i", &a, &b);
return (a - b);
}
float divideFloat() {
float a, b;
scanf(" %f %f", &a, &b);
return (a / b);
}
int divideInt() {
float a, b;
scanf(" %f %f", &a, &b);
return (a / b);
}
int modulo() {
int a, b;
scanf(" %i %i", &a, &b);
return (a % b);
}
int times() {
int a, b;
scanf(" %i %i", &a, &b);
return (a * b);
}
long int power() {
int base, exp, result = 1;
scanf(" %i %i", &base, &exp);
if (exp == 0)
return 1;
for (int i = 1; i <= exp; i++) {
result *= base;
}
return result;
}
long long int factorial() {
int number;
long long int result = 1;
scanf(" %i", &number);
if (number < 0) {
return -1;
} else if (number == 0) {
return 1;
} else {
for (int i = 0; i < number; i++) {
result *= (number - i);
}
return result;
}
}
int sums() {
int member, result = 0, numberOfMembers;
scanf(" %i", &numberOfMembers);
int temp = numberOfMembers;
while (temp > 0) {
scanf("%i", &member);
result += member;
temp--;
}
return result;
}
float average() {
float result = 0;
int member, numberOfMembers;
scanf(" %i", &numberOfMembers);
int temp = numberOfMembers;
if (numberOfMembers == 0) {
return 0;
} else {
while (temp > 0) {
scanf(" %i", &member);
result += member;
--temp;
}
return (result / numberOfMembers);
}
}
long long int binomialCoeficient() {
int n, k;
scanf(" %i %i", &n, &k);
if (n < k || k < 0 || n < 0) {
return -1;
}
long long int test = (factorialWithArgument(n) / (factorialWithArgument(n - k) * factorialWithArgument(k)));
return test;
}
int is_prime() {
int a;
scanf(" %i", &a);
if (a <= 1)
return 0;
for (int i = 2; i < a; i++) {
if (a % i == 0)
return 0;
}
return 1;
}
long long int factorialWithArgument(int a) {
long long int result = 1;
if (a < 0) {
return -1;
} else if (a == 0) {
return 1;
} else {
for (int i = 0; i < a; i++) {
result *= (a - i);
}
return result;
}
}
@@ -0,0 +1,39 @@
/* TAGS: min c */
/* LD_OPTS: -lm */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <complex.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
int main(void)
{
double complex z = 2 + 2*I;
double complex res = cexp( z );
double img = cimag(res);
double real = creal(res);
int i_img = (int) img;
printf("%i %i\n", (int) real, (int) img);
if ( i_img != 6 ) printf("NOK!\n");
printf("%i\n\t%i + %ii\n", 42, (int)real, (int)img);
}
@@ -0,0 +1,41 @@
/* TAGS: min c */
/* LD_OPTS: -lm */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <complex.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
int main(void)
{
float complex beg = 4.54 + 2.56*I;
float complex z = cexpf(beg);
float img = cimagf(z);
float real = crealf(z);
int i_img = (int) img;
int i_real = (int) real;
printf("%i %i\n", (int) real, (int) i_img);
if ( i_img != 2 ) printf("NOK img!\n");
if ( i_real != 4 ) printf("NOK real!\n");
printf("%i\n\t%i + %i\n", 42, (int)real, (int)img);
}
@@ -0,0 +1,42 @@
/* TAGS: min c */
/* LD_OPTS: -lm */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <complex.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
int main(void)
{
long double complex z = 1.25 + 2.54*I;
long double complex res = cexpl( z );
long double img = cimagl(res);
long double real = creall(res);
if ( real + 2.877 < 0
&& real + 2.8776 > 0
&& img - 1.975 > 0
&& img - 1.976 < 0 )
printf( "OK\n" );
else
printf( "NOK\n" );
printf("%i\n\t%i + %i\n", 42, (int)real, (int)img);
}
@@ -0,0 +1,83 @@
/* TAGS: min c */
/* LD_OPTS: -lm */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <complex.h>
#include <math.h>
#include <stdio.h>
void FooFloat() {
float complex initial_value = 3.14f + 4.2*I;
float complex exponent = 2.0f - 1.12*I;
float complex result = cpowf(initial_value, exponent);
float real_part = crealf(result);
float imag_part = cimagf(result);
int int_real = (int) real_part;
int int_imag = (int) imag_part;
printf("%i %i\n", int_real, int_imag);
if (int_real == 77 && int_imag == 0) puts("Okay");
else puts("Nok");
result = csinf(initial_value);
real_part = crealf(result);
imag_part = cimagf(result);
int_real = (int) real_part;
int_imag = (int) imag_part;
printf("%i %i\n", int_real, int_imag);
if (int_real == 0 && int_imag == -33) puts("Okay");
else puts("Nok");
}
void FooDouble() {
double complex initial_value = 3.14 + 4.2*I;
double complex exponent = 2.0f - 1.12*I;
double complex result = cpow(initial_value, exponent);
double real_part = creal(result);
double imag_part = cimag(result);
int int_real = (int) real_part;
int int_imag = (int) imag_part;
printf("%i %i\n", int_real, int_imag);
if (int_real == 77 && int_imag == 0) puts("Okay");
else puts("Nok");
result = csin(initial_value);
real_part = creal(result);
imag_part = cimag(result);
int_real = (int) real_part;
int_imag = (int) imag_part;
printf("%i %i\n", int_real, int_imag);
if (int_real == 0 && int_imag == -33) puts("Okay");
else puts("Nok");
}
int main(void)
{
FooFloat();
FooDouble();
//TODO: Crashing with floating point exception
//FooLongDouble();
}
+32
View File
@@ -0,0 +1,32 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
static const int a [] = { 4, 3, 7, 5, 9, -4 };
static const int b [] = { 1, -1, 5, -2, 3, 5 };
int main (void)
{
int result = 0;
for (int i = 0; i < 6; ++i)
result += a[i] * b[i];
printf ("%d\n", result);
return 0;
}
+43
View File
@@ -0,0 +1,43 @@
/* TAGS: min c */
/* TEST: 12 */
/* TEST: 26 */
/* TEST: 2 */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
unsigned int fib (unsigned int i)
{
if (i == 0)
return 0;
else if ((i == 1) || (i == 2))
return 1;
else
return fib (i - 1) + fib (i - 2);
}
int main (int argc, char **argv)
{
if (argc < 2)
return 1;
int n = atoi (argv [1]);
printf ("%u\n", fib (n));
return 0;
}
+37
View File
@@ -0,0 +1,37 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include <stdio.h>
#include <float.h>
void do_calc( float first, float second ) {
float result = fmodf( first, second );
printf( "%i\n", (int)result );
if ( fabsf( result - 0.4f ) < FLT_EPSILON ) printf( "Okay.\n" );
else printf( "Nok.\n" );
}
int main() {
printf( "Begin %i %i %i\n\t***\n", (int)123.456f, 2, 4);
float fix = 5.4f;
for ( float i = 0.1f; i <= 0.5f; i += 0.1f ) {
do_calc( fix, i );
}
}
@@ -0,0 +1,34 @@
/* TAGS: min c */
#include <assert.h>
#include <stdio.h>
// Compiler should generate bitcast in llvm.global_ctors and llvm.global_dtors.
int x = 0, y = 0;
__attribute__((constructor(1), destructor(1))) void assert_zeroes() {
assert( x == 0 );
assert( y == 0 );
putchar( 'c' );
}
__attribute__((constructor(2))) int increase_and_return() {
++x;
return x;
}
__attribute__((destructor(2))) int decrease_and_return() {
--x;
return x;
}
int main() {
assert( x == 1 );
int inc_x = increase_and_return();
assert( x == inc_x );
int dec_x = decrease_and_return();
assert( x == dec_x );
}
@@ -0,0 +1,32 @@
/* TAGS: min c */
#include <assert.h>
#include <stdio.h>
int x = 0, y = 0;
#define CTOR(I) __attribute__((constructor(I))) void ct ## I() { assert( x == I - 1 ); ++x; }
__attribute__((constructor(0))) void ct_first() { assert( x == 0 ); }
CTOR( 1 );
CTOR( 2 );
CTOR( 3 );
__attribute__((constructor)) void ct_outOfOrder() { ++y; }
CTOR( 4 );
int main() {
assert( x == 4 );
assert( y == 1 );
}
#define DTOR(I) __attribute__((destructor(I))) void dt ## I() { assert( x == I ); --x; }
DTOR( 4 );
DTOR( 3 );
DTOR( 2 );
DTOR( 1 );
__attribute__((destructor(0))) void dt_last() {
assert( x == 0 );
assert( y == 1 );
putchar( 'a' );
}
@@ -0,0 +1,33 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
static int gArr[10] = {1, 2, 3, 3, 2, 1, 1, 2, 3, 42};
int main() {
printf("%i\n", gArr[0]);
printf("%i\n", gArr[1]);
printf("%i\n", gArr[2]);
printf("%i\n", gArr[3]);
printf("%i\n", gArr[4]);
printf("%i\n", gArr[5]);
printf("%i\n", gArr[6]);
printf("%i\n", gArr[7]);
printf("%i\n", gArr[8]);
printf("%i\n", gArr[9]);
}
@@ -0,0 +1,42 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdio>
#include <string.h>
class A {
public:
char name[256];
A(const char *nameIn) {
printf("class A constructor!\n");
strcpy(name, nameIn);
}
~A(void) {
printf("Class A destructor!\n");
}
};
A global("Global");
int main(void) {
printf("Variable name %s\n", global.name);
return 0;
}
@@ -0,0 +1,41 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
static char someglobal = 1;
static int gInt[2] = {42, 43};
int writeit()
{
write(2,&someglobal,1);
someglobal++;
write(2,&someglobal,1);
return 0;
}
int main(void)
{
someglobal = 0x68;
writeit();
gInt[1] = 44;
printf("\n");
printf("%i, %i\n", gInt[0], gInt[1]);
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
/* TAGS: min c */
/*
* Copyright (c) 2019 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main() {
puts("Hello world!");
}
+22
View File
@@ -0,0 +1,22 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2019 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
}
+61
View File
@@ -0,0 +1,61 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
static const int g = 8;
int foo (void)
{
const int *p = &g;
if ((*p) > 12)
return 17;
char str [] = "Hello, world!\n";
for (int i = 0; i < 14; ++i)
putchar (str [i]);
putchar('H');
putchar('e');
putchar('l');
putchar('l');
putchar('o');
putchar(',');
putchar(' ');
putchar('w');
putchar('o');
putchar('r');
putchar('l');
putchar('d');
putchar('!');
putchar('\n');
printf ("And now from printf()!\n");
int i;
i = 4 + (*p);
printf ("Calculated %d\n", i + 42);
return 0;
}
int main (int argc, char **argv)
{
return foo ();
}
@@ -0,0 +1,37 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
struct A {
std::string value;
A( std::string&& str ) : value( std::move( str ) ) {
std::cout << "I was stolen from!:" << str << std::endl;
}
void shout() {
std::cout << value << std::endl;
}
};
int main() {
std::cout << "Hello World!" << std::endl;
std::string precious = "My little precious";
A a( std::move( precious ) );
a.shout();
}
+34
View File
@@ -0,0 +1,34 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main (int argc, char **argv)
{
int array [] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int result = 0;
for (int i = 0; i < 10; ++i)
{
result += array [i];
printf ("result now: %d\n", result);
}
printf ("final result: %d\n", result);
return 0;
}
@@ -0,0 +1,21 @@
/* TAGS: min c */
#include <stdio.h>
static const int A [] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
static const int b [] = { 4, 7, 11 };
static int c [3] = { 0 };
int main (int argc, char **argv)
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
c [i] += A [3 * i + j] * b [j];
}
}
printf ("c = ( %d, %d, %d )^T\n", c [0], c [1], c [2]);
return 0;
}
@@ -0,0 +1,42 @@
/* TAGS: min c */
/* TEST: /usr */
/* TEST: /eqeqeqwe */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
int main (int argc, char **argv)
{
if (argc != 2)
{
puts ("error: need exactly one argument");
return 1;
}
DIR *dir = opendir (argv [1]);
if (!dir)
perror ("opendir");
else
closedir (dir);
printf ("errno: %d\n", errno);
return 0;
}
@@ -0,0 +1,40 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <string>
struct A {
std::string message;
void shout( const std::string& target ) {
std::cout << "He shouted at " << target << " with this words:" << std::endl;
std::cout << "\t" << message << std::endl;
}
};
void challenge( A*& a ) {
a = new A( { "How dare you touch my duck?" } );
std::cout << "INFO: challenge is prepared" << std::endl;
}
int main() {
A* ptr;
challenge( ptr );
ptr->shout( "Ivan" );
delete ptr;
}
+31
View File
@@ -0,0 +1,31 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main (int argc, char **argv)
{
int x = 93;
int *y = &x;
int **z = &y;
printf (" x: %d\n", x);
printf (" *y: %d\n", *y);
printf ("**z: %d\n", **z);
return 0;
}
@@ -0,0 +1,22 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main() {
printf("Hello %.2f %.2f %i %.2f %.2f %.2f %.2f %.2f %i %.2f and World!\n", 4.40f, 4.41f, -30, 4.424324f, 4.43f, 4.44f, 4.45f, 4.46f, 30, 4.47f );
}
+97
View File
@@ -0,0 +1,97 @@
/* TAGS: min cpp */
/* LD_OPTS: -lpthread */
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static pthread_cond_t gCond;
static pthread_mutex_t gLock;
static int gFlag = 0;
__thread int tls_data1;
__thread int tls_data2;
typedef struct {
int data1;
int data2;
} thread_parm_t;
void bar() {
printf("bar(), tls data=%d %d\n", tls_data1, tls_data2);
return;
}
void foo() {
printf("foo(), tls data=%d %d\n", tls_data1, tls_data2);
bar();
}
void *theThread(void *parm)
{
thread_parm_t *gData;
pthread_mutex_lock(&gLock);
pthread_cond_wait(&gCond, &gLock);
gFlag += 1;
gData = (thread_parm_t*)parm;
tls_data1 = gData->data1;
tls_data2 = gData->data2;
foo();
pthread_mutex_unlock(&gLock);
return NULL;
}
int main(int argc, char **argv) {
int rc=0, i;
pthread_t thread[2];
thread_parm_t gData[2];
printf("Create threads\n");
pthread_mutex_init(&gLock, NULL);
pthread_cond_init(&gCond, NULL);
for (i=0; i < 2; i++) {
gData[i].data1 = i;
gData[i].data2 = (i+1)*2;
rc = pthread_create(&thread[i], NULL, theThread, &gData[i]);
if (rc) {
printf("Failed with %d at pthread_create()", rc);
exit(1);
}
}
// synchronize output. this gets printed before threads print
printf("Wait for the threads to complete, and release their resources\n");
fflush(stdout);
while (gFlag < 2) {
pthread_cond_signal(&gCond);
}
for (i=0; i < 2; i++) {
rc = pthread_join(thread[i], NULL);
if (rc) {
printf("Failed with %d at pthread_join()", rc);
exit(1);
}
}
printf("Main completed\n");
return 0;
}
+45
View File
@@ -0,0 +1,45 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
void fill() {
printf(" F ");
}
int compare( const void* a, const void* b ) {
int arg1 = *( const int* ) a;
int arg2 = *( const int* ) b;
if ( arg1 < arg2 ) return -1;
if ( arg1 > arg2 ) return 1;
return 0;
}
int main() {
int arr[] = { - 2, 5, 6, 8, 10, 12 };
int size = sizeof arr / sizeof *arr;
qsort( arr, size, sizeof( int ), compare );
int prev = -42;
printf( "Sorted: " );
for ( int i = 0; i < size; ++i ) {
printf("%i ", arr[i] );
fill();
}
printf("\n");
}
@@ -0,0 +1,96 @@
/* TAGS: min cpp */
/* TEST: 23 */
/* TEST: 43 */
/* TEST: 435 */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
int zero() {
return 0;
}
int one() {
return 1;
}
int two() {
return 2;
}
int four() {
return 4;
}
int many() {
return 42;
}
using zTy = int(*)();
template<typename baseTy>
using fTy = int(baseTy*, size_t, int);
int compare(const void* a, const void* b) {
printf("Comparing:\n");
zTy arg1 = *(zTy *) a;
printf("\tArg1 %i\n", arg1());
zTy arg2 = *(zTy *) b;
printf("\tArg2 %i\n", arg2());
int rhs = arg1();
int lhs = arg2();
if (rhs < lhs) return -1;
if (rhs > lhs) return 1;
return 0;
}
template<typename Func>
int firstLevel(Func *f, size_t size, int iter) {
int base = f[0]();
for (auto i = 0U; i < iter; ++i) {
base += f[i % size]();
printf("Iter: %i \tbase: %i\n", i, base);
}
printf("Before sort:\n");
for (auto i = 0U; i < size; ++i) {
printf("\t%i", f[i]());
}
printf("\n");
qsort(f, size, sizeof(zTy), compare);
printf("Sorted:\n");
for (auto i = 0U; i < size; ++i) {
printf("\t%i", f[i]());
}
printf("\n");
return base;
}
int main(int argc, char* argv[]) {
int a = atoi(argv[1]);
int(*funcs[])() = {two, many, four, zero, one};
int result = firstLevel<int(*)()>(funcs, 5, a);
}
@@ -0,0 +1,43 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
int x = -11;
int y = abs (x);
printf ("11 : %i\n", y);
srand (13);
int i = rand ();
printf ("rand: %i\n", i);
char str [30] = "2030300 This is a test";
char *ptr;
long ret;
printf ("str: \"%s\"\n", str);
ret = strtol (str, &ptr, 10);
printf ("Number: %ld\n", ret);
printf ("Remainder: \"%s\"\n", ptr);
return 0;
}
+66
View File
@@ -0,0 +1,66 @@
/* TAGS: min c */
/* TEST: readdir.c */
/* TEST: /tmp */
/* TEST: file-that-does-not-exist */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
static void lookup (const char *arg)
{
DIR *dirp;
struct dirent *dp;
if ((dirp = opendir (".")) == NULL)
{
perror ("couldn't open '.'");
return;
}
do
{
errno = 0;
if ((dp = readdir (dirp)) != NULL)
{
if (strcmp (dp->d_name, arg) != 0)
continue;
printf ("found %s\n", arg);
closedir (dirp);
return;
}
} while (dp != NULL);
if (errno != 0)
perror ("error reading directory");
else
printf ("failed to find %s\n", arg);
closedir (dirp);
return;
}
int main (int argc, char *argv[])
{
for (int i = 1; i < argc; i++)
lookup (argv [i]);
return 0;
}
@@ -0,0 +1,32 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
static const int array [10] = { 4, 7, 9, 13, 1, 7, 1, 0, 4, 5 };
int main (void)
{
int result = 0;
for (int i = 0; i < 10; ++i)
result += array [i];
printf ("Result: %d\n", result);
return 0;
}
+24
View File
@@ -0,0 +1,24 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
int main (int argc, char **argv)
{
exit (EXIT_SUCCESS);
return 1;
}
@@ -0,0 +1,29 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
int main (void)
{
int i = 5;
for (i = 0; i < 85; ++i) { }
printf ("i: %d\n", i);
return 0;
}
+29
View File
@@ -0,0 +1,29 @@
/* TAGS: min c */
/* CC_OPTS: */
/* LD_OPTS: */
/* LIFT_OPTS: EXP +explicit_args +explicit_args_count 8 !abi_libraries */
/* TEST: --help */
/* STDIN: F/inputs.txt */
/* TEST: --version */
/* TEST: --extract nonsense.txt */
/* STDIN: Hello World\nThis Should Be Together */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
int main (int argc, char **argv)
{
return 0;
}
+59
View File
@@ -0,0 +1,59 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
struct Book
{
char title [50];
char author [50];
char subject [100];
int book_id;
};
void printBook (struct Book book);
int main ()
{
struct Book Book1;
struct Book Book2;
strcpy (Book1.title, "C Programming");
strcpy (Book1.author, "Nuha Ali");
strcpy (Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
strcpy (Book2.title, "Telecom Billing");
strcpy (Book2.author, "Zara Ali");
strcpy (Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
printBook (Book1);
printBook (Book2);
return 0;
}
void printBook (struct Book book)
{
printf ("Book title: %s\n", book.title);
printf ("Book author: %s\n", book.author);
printf ("Book subject: %s\n", book.subject);
printf ("Book book_id: %d\n", book.book_id);
printf ("\n");
}
@@ -0,0 +1,47 @@
/* TAGS: min cpp */
/* TEST: */
/* STDIN: 4\n4\n */
/* TEST: */
/* STDIN: 5\n5\n */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <string>
template< typename F >
struct Holder {
F a;
F b;
};
int foo( std::string str ) {
std::cout << "Foo: " << str << std::endl;
return 1;
}
int boo( std::string str ) {
std::cout << "Boo: " << str << std::endl;
return 2;
}
int main() {
Holder< int(*)(std::string) > h { foo, boo };
int a;
std::cin >> a;
if ( a % 2 ) h.a( "hello" );
else h.b( "world" );
}
@@ -0,0 +1,73 @@
/* TAGS: min cpp */
/* TEST: 42 */
/* TEST: -543 */
/* TEST: 21 */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
template< typename FuncPtr, typename Num = int >
int specialSum( Num* arr, int size, FuncPtr ptr, int base = 0 ) {
int result = base;
for ( int i = 0; i < size; ++i ) {
result = ptr( result, arr[i] );
}
return result;
}
int add( int a, int b ) {
return a + b;
}
int dec( int a, int b ) {
return a - 1;
}
int joker( int a, int b ) {
if ( a > b ) return dec ( a, b );
if ( a < b ) return add ( a, b );
return 0;
}
template< typename ordFunc, typename getFunc >
auto specialFunc( ordFunc ord, getFunc get, int input ) {
int salt = 42;
auto g = get( input, salt );
int arr[3] = { input, salt, g };
if ( specialSum( arr, 3, ord) > 0 ) return add;
else return dec;
}
int main( int argc, char* argv[] ) {
int arr[10] = { 1, 4, 32, -54, 5, 6, 76, 12, 45, -89 };
int res = specialSum( arr, 10, add );
printf( "%i\n", res );
res = specialSum( arr, 10, dec );
printf( "%i\n", res );
res = specialSum( arr, 10, joker );
printf( "%i\n", res );
auto special = specialFunc( add, dec, std::stoi( argv[1] ) );
printf( "%i\n", special( 37, 5 ) );
}
+68
View File
@@ -0,0 +1,68 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <memory>
#include <string>
#include <iostream>
struct Parent {
protected:
std::string name;
public:
Parent( const std::string& str ) : name( str ) {
std::cout << "Parent is setting name!" << std::endl;
}
virtual ~Parent() = default;
virtual void shout() = 0;
};
struct Angry : Parent {
protected:
int age = 42;
public:
Angry( const std::string& str ) : Parent( str ) {
std::cout << "Angry person was born" << std::endl;
}
void shout() override {
std::cout << "I am angry! I am: " << name << std::endl;
}
};
struct Calm : Parent {
Calm( const std::string& str ) : Parent( str ) {
std::cout << "Calm person was born" << std::endl;
}
void shout() override {
std::cout << "Me calm. Me: " << name << std::endl;
}
};
int main() {
Calm a( "Caleb" );
Parent* oldMan = new Angry( "Ivan" );
// This is the troublesome one
oldMan->shout();
std::cout << "And so shout happened" << std::endl;
delete oldMan;
std::cout << "Story is now over" << std::endl;
}
@@ -0,0 +1,63 @@
/* TAGS: min cpp */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <memory>
#include <string>
#include <iostream>
struct Parent {
protected:
std::string name;
public:
Parent( const std::string& str ) : name( str ) {
std::cout << "Parent is setting name!" << std::endl;
}
virtual ~Parent() = default;
virtual void shout() = 0;
};
struct Angry : Parent {
protected:
int age = 42;
public:
Angry( const std::string& str ) : Parent( str ) {
//Empty
}
void shout() override {
std::cout << "I am angry! I am: " << name << std::endl;
}
};
struct Calm : Parent {
Calm( const std::string& str ) : Parent( str ) {
//Empty
}
void shout() override {
std::cout << "Me calm. Me: " << name << std::endl;
}
};
int main() {
Parent* oldMan = new Angry( "Ivan" );
oldMan->shout();
delete oldMan;
}
+30
View File
@@ -0,0 +1,30 @@
/* TAGS: min c */
/*
* Copyright (c) 2018 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
int main(void)
{
unsigned int x = 0xdeadbee0;
unsigned int n = 3;
__asm__ __volatile__ ( "bts %1,%0": "+rm"(x) : "r"(n));
printf("x is: %08x\n", x);
return 0;
}
@@ -0,0 +1,2 @@
TAGS: gzip c gnu
LIFT_OPTS:
+55
View File
@@ -0,0 +1,55 @@
# Copyright (c) 2019 Trail of Bits, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
def strip_whole_config(filename):
if not filename.endswith(".config"):
return ""
filename = filename.rstrip(".config")
basename, ext = os.path.splitext(filename)
return basename
def get_binaries(directory):
result = set()
for f in os.listdir(directory):
filename = strip_whole_config(f)
if filename:
result.add(filename)
return result
def get_tags(config):
with open(config, 'r') as f:
line = f.readline().rstrip('\n')
tokens = line.split(' ')
if tokens[0] != 'TAGS:':
return []
return tokens[1:]
def get_bin2tags(directory):
result = {}
for f in os.listdir(directory):
filename = strip_whole_config(f)
if not filename:
continue
tags = get_tags(os.path.join(directory, f))
if filename not in result:
result[filename] = tags
else:
result[filename].append(tags)
return result
def get_cfg(directory, name):
return os.path.join(directory, name + '.cfg')