mirror of
https://github.com/lifting-bits/mcsema
synced 2026-06-08 15:31:09 +00:00
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:
+1
-1
@@ -1 +1 @@
|
||||
9bddfa16afa6fea266c27b3538380ee17d75cb4b
|
||||
3b9b36f4efbfe46ef82f1eaae8d117b3755878e0
|
||||
|
||||
@@ -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
|
||||
|- ...
|
||||
```
|
||||
@@ -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
|
||||
Executable
+176
@@ -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()
|
||||
Executable
+372
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
What a beauty!
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
Cras cras, semper cras sic evadit eatas.
|
||||
Binary file not shown.
Executable
+65
@@ -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()
|
||||
@@ -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)
|
||||
Executable
+632
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 );
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 ) );
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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')
|
||||
Reference in New Issue
Block a user