Skip to content
This repository has been archived by the owner on Jan 18, 2021. It is now read-only.

Commit

Permalink
I push the button
Browse files Browse the repository at this point in the history
  • Loading branch information
pgoodman committed Oct 3, 2016
0 parents commit 21040a5
Show file tree
Hide file tree
Showing 163 changed files with 40,382 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set logging off
set breakpoint pending on
set print demangle on
set print asm-demangle on
set print object on
set print static-members on
set disassembly-flavor intel
set backtrace limit 20
set language c++

b granary_curiosity
b granary_unreachable

9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bin/*
.project
.cproject
.settings/*
test/*_01
test/*_02
test/*_03


185 changes: 185 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# Copyright 2015 Peter Goodman, all rights reserved.

.PHONY: all clean

GRANARY_CC ?= clang-3.6
GRANARY_CXX ?= clang++-3.6

# Where is Granary's source code located?
GRANARY_SRC_DIR ?= $(shell pwd)
GRANARY_LIB_DIR := $(GRANARY_SRC_DIR)/third_party
GRANARY_GEN_DIR := $(GRANARY_SRC_DIR)/gen

# What OS are we compiling for?
GRANARY_OS ?= decree

# Where will Granary run? Specify `kernel` for kernel space, and `user` for
# user space.
GRANARY_WHERE ?= user

# What type of build should be perform?
GRANARY_TARGET ?= debug

# Useful for distinguishing different kinds of builds.
GRANARY_TRIPLE := $(GRANARY_TARGET)_$(GRANARY_OS)_$(GRANARY_WHERE)

# Where should we emit object files and the executable?
GRANARY_BIN_DIR ?= $(GRANARY_SRC_DIR)/bin/$(GRANARY_TRIPLE)

# Should we assume that Granary will be executed with Valgrind?
GRANARY_WITH_VALGRIND ?= 0

# Compiler warnings that are explicitly disabled.
GRANARY_DISABLED_WARNINGS := -Wno-gnu-anonymous-struct
GRANARY_DISABLED_WARNINGS += -Wno-gnu-conditional-omitted-operand
GRANARY_DISABLED_WARNINGS += -Wno-long-long
GRANARY_DISABLED_WARNINGS += -Wno-gnu-statement-expression
GRANARY_DISABLED_WARNINGS += -Wno-nested-anon-types
GRANARY_DISABLED_WARNINGS += -Wno-extended-offsetof
GRANARY_DISABLED_WARNINGS += -Wno-c++98-compat-pedantic -Wno-c++98-compat
GRANARY_DISABLED_WARNINGS += -Wno-padded
GRANARY_DISABLED_WARNINGS += -Wno-unused-macros
GRANARY_DISABLED_WARNINGS += -Wno-missing-variable-declarations
GRANARY_DISABLED_WARNINGS += -Wno-missing-prototypes
GRANARY_DISABLED_WARNINGS += -Wno-packed
GRANARY_DISABLED_WARNINGS += -Wno-global-constructors
GRANARY_DISABLED_WARNINGS += -Wno-exit-time-destructors
GRANARY_DISABLED_WARNINGS += -Wno-disabled-macro-expansion
GRANARY_DISABLED_WARNINGS += -Wno-date-time
GRANARY_DISABLED_WARNINGS += -Wno-reserved-id-macro

# Arch-specific flags.
GRANARY_ARCH_FLAGS := -m64 -mtune=generic -fPIC -ffreestanding
GRANARY_ARCH_FLAGS += -ftls-model=initial-exec -mno-red-zone
GRANARY_ARCH_FLAGS += -fno-common -fno-builtin
GRANARY_ARCH_FLAGS += -fno-stack-protector -minline-all-stringops

# Flags that are common to both C and C++ compilers.
GRANARY_COMMON_FLAGS :=
GRANARY_COMMON_FLAGS += -I$(GRANARY_SRC_DIR)
GRANARY_COMMON_FLAGS += -Wall -Werror -Wpedantic
GRANARY_COMMON_FLAGS += $(GRANARY_DISABLED_WARNINGS)
GRANARY_COMMON_FLAGS += -DGRANARY_WHERE_$(GRANARY_WHERE)
GRANARY_COMMON_FLAGS += -DGRANARY_OS_$(GRANARY_OS)
GRANARY_COMMON_FLAGS += -DGRANARY_TARGET_$(GRANARY_TARGET)
GRANARY_COMMON_FLAGS += -DGOOGLE_PROTOBUF_NO_RTTI

GRANARY_SANITIZER ?=

# Optimization and debug information level.
ifeq (debug,$(GRANARY_TARGET))
GRANARY_COMMON_FLAGS += -O0 -g3 -fno-inline
ifneq (,$(GRANARY_SANITIZER))
GRANARY_COMMON_FLAGS += -fsanitize=$(GRANARY_SANITIZER)
endif
else
GRANARY_COMMON_FLAGS += -Oz -g3
endif

# Flags to pass to the various compilers.
#
# Note: We don't pass in Musl as a system include so that libc++ can pick up
# on specific system-defined macros in libc that Musl doesn't provide.
#
# Note: We need to pass in libc++ as we're not guaranteed that the
# distribution version of libc++ exactly matches the Granary version, and
# even minor differences can result in missing symbols.
GRANARY_CC_FLAGS := -std=c11 $(GRANARY_COMMON_FLAGS) $(GRANARY_ARCH_FLAGS)
GRANARY_CXX_FLAGS := -std=c++11 #-stdlib=libstdc++
GRANARY_CXX_FLAGS += $(GRANARY_COMMON_FLAGS) $(GRANARY_ARCH_FLAGS)
GRANARY_CXX_FLAGS += -fno-exceptions -fno-asynchronous-unwind-tables -fno-rtti
GRANARY_CXX_FLAGS += -isystem $(GRANARY_LIB_DIR)/gflags/include

# C, C++, and assembly files in Granary.
GRANARY_SRC_FILES := $(shell find $(GRANARY_SRC_DIR)/granary/ -name '*.cc' -or -name '*.c' -or -name '*.S' -type f)
GRANARY_SRC_FILES += $(shell find $(GRANARY_SRC_DIR)/third_party/ -name '*.cc' -or -name '*.c' -or -name '*.S' -type f)

DUMP_SRC_FILES = $(GRANARY_SRC_DIR)/coverage.cc
DUMP_SRC_FILES += $(GRANARY_SRC_DIR)/granary/code/index.cc
DUMP_SRC_FILES += $(GRANARY_SRC_DIR)/granary/base/breakpoint.cc
DUMP_SRC_FILES += $(GRANARY_SRC_DIR)/granary/base/interrupt.cc
DUMP_SRC_FILES += $(GRANARY_LIB_DIR)/xxhash/xxhash.c
DUMP_OBJECT_FILES := $(addsuffix .o, $(subst $(GRANARY_SRC_DIR),$(GRANARY_BIN_DIR),$(DUMP_SRC_FILES)))

PLAY_SRC_FILES = $(GRANARY_SRC_DIR)/play.cc $(GRANARY_SRC_DIR)/play.cc $(GRANARY_SRC_FILES)
PLAY_OBJECT_FILES := $(addsuffix .o, $(subst $(GRANARY_SRC_DIR),$(GRANARY_BIN_DIR),$(PLAY_SRC_FILES)))

SNAPSHOT_SRC_FILES := $(GRANARY_SRC_DIR)/snapshot.cc
SNAPSHOT_SRC_FILES += $(GRANARY_SRC_DIR)/granary/os/snapshot.cc
SNAPSHOT_SRC_FILES += $(GRANARY_SRC_DIR)/granary/os/decree_user/snapshot.cc
SNAPSHOT_SRC_FILES += $(GRANARY_SRC_DIR)/granary/base/breakpoint.cc
SNAPSHOT_SRC_FILES += $(GRANARY_SRC_DIR)/granary/base/interrupt.cc
SNAPSHOT_OBJ_FILES := $(addsuffix .o, $(subst $(GRANARY_SRC_DIR),$(GRANARY_BIN_DIR),$(SNAPSHOT_SRC_FILES)))

# Compile C++ files to object files.
$(GRANARY_BIN_DIR)/%.pb.cc.o :: $(GRANARY_SRC_DIR)/%.pb.cc
@echo "Building CXX object $@"
@mkdir -p $(@D)
@$(GRANARY_CXX) -Weverything -Wno-sign-conversion -Wno-shorten-64-to-32 $(GRANARY_CXX_FLAGS) -c $< -o $@

# Compile C++ files to object files.
$(GRANARY_BIN_DIR)/%.cc.o :: $(GRANARY_SRC_DIR)/%.cc
@echo "Building CXX object $@"
@mkdir -p $(@D)
@$(GRANARY_CXX) -Weverything $(GRANARY_CXX_FLAGS) -c $< -o $@

# Compile C files to object files.
$(GRANARY_BIN_DIR)/%.c.o :: $(GRANARY_SRC_DIR)/%.c
@echo "Building C object $@"
@mkdir -p $(@D)
@$(GRANARY_CC) $(GRANARY_CC_FLAGS) -c $< -o $@

# Compile assembly files to object files.
$(GRANARY_BIN_DIR)/%.S.o :: $(GRANARY_SRC_DIR)/%.S
@echo "Building ASM object $@"
@mkdir -p $(@D)
@$(GRANARY_CC) $(GRANARY_COMMON_FLAGS) $(GRANARY_ARCH_FLAGS) -c $< -o $@

# Build the Granary executable.
$(GRANARY_BIN_DIR)/grrplay: $(PLAY_OBJECT_FILES)
@echo "Linking $@"
@$(GRANARY_CXX) \
$(GRANARY_CXX_FLAGS) \
-o $@ \
$^ \
$(GRANARY_LIB_DIR)/xed-intel64/lib/libxed.a \
$(GRANARY_LIB_DIR)/gflags/lib/libgflags_nothreads.a \
-lpthread \
-static-libstdc++ \
-static-libgcc

# Build the Granary executable.
$(GRANARY_BIN_DIR)/grrshot: $(SNAPSHOT_OBJ_FILES)
@echo "Linking $@"
@$(GRANARY_CXX) \
$(GRANARY_CXX_FLAGS) \
-o $@ \
$^ \
$(GRANARY_LIB_DIR)/gflags/lib/libgflags_nothreads.a \
-lpthread \
-static-libstdc++ \
-static-libgcc

# Build the program to print out a code cache.
$(GRANARY_BIN_DIR)/grrcov: $(DUMP_OBJECT_FILES)
@echo "Linking $@"
@$(GRANARY_CXX) \
$(GRANARY_CXX_FLAGS) \
-o $@ \
$^ \
$(GRANARY_LIB_DIR)/gflags/lib/libgflags_nothreads.a \
-lpthread \
-static-libstdc++ \
-static-libgcc

clean:
@rm -rf $(GRANARY_BIN_DIR)

all: $(GRANARY_BIN_DIR)/grrplay $(GRANARY_BIN_DIR)/grrshot $(GRANARY_BIN_DIR)/grrcov
@echo "Done."

install:
mkdir -p $(GRANARY_PREFIX_DIR)/bin
cp $(GRANARY_BIN_DIR)/grrplay $(GRANARY_PREFIX_DIR)/bin
cp $(GRANARY_BIN_DIR)/grrshot $(GRANARY_PREFIX_DIR)/bin
cp $(GRANARY_BIN_DIR)/grrcov $(GRANARY_PREFIX_DIR)/bin
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Granary3
========

This is a simple implementation of an x86 to amd64 binary translator. The
purpose of this binary translator is for use with DECREE binaries.

Key features:
* Support for self-modifying code (e.g. JIT compilers).
* Simple block tracing infrastructure (superblock formation).
* Code cache persistence (avoids translation overheads across separate runs).
* Multi-processing support (allows multiple communicating, 32-bit processes
to be emulated within a single 64-bit address space).

### Dependencies

```
sudo apt-get install -y git build-essential
sudo apt-get install -y clang-3.5 clang++-3.5 llvm-3.5-dev libc++1 libc++-dev
sudo apt-get install -y libgflags-dev libprotobuf-dev libprotoc-dev
```

### Compiling
#### Debug Build
```sh
make clean all
```
#### Release Build
```sh
make all GRANARY_TARGET=release
```

### Running

There are two steps to running Granary: snapshotting, and record/replaying. Snapshotting creates an initial image of the binary after `execve`. Record/replaying takes an input testcase (formatted as a protocol buffer) and attempts to replay that testcase. The replay can be recorded or mutated as well.

#### Snapshotting
If you are on an AMD64 port of the CGC kernel, then you can do this:
```sh
./bin/debug_linux_user/grrshot --num_exe=1 --exe_dir=/path --exe_prefix=CADET_000 --snapshit_dir=/tmp/snapshot
```
This will create a snapshot of `/path/CADET_00001` and store the snapshot into the `/tmp/snapshot` directory.

If you are on a non-CGC AMD64 port, then make sure to do the following first:
```sh
cgc2elf /path/CADET_00001
```

#### Replaying
```sh
./bin/debug_linux_user/grrplay --num_exe=1 --snapshot_dir=/tmp/snapshot --persist_dir=/tmp/persist --input=/path/to/testcase
```

#### Replay + Recording
```sh
./bin/debug_linux_user/grrplay --num_exe=1 --snapshot_dir=/tmp/snapshot --persist_dir=/tmp/persist --input=/path/to/testcase --output_dir=/tmp/out
```

#### Replay + Recording + Mutating
```sh
./bin/debug_linux_user/grrplay --num_exe=1 --snapshot_dir=/tmp/snapshot --persist_dir=/tmp/persist --input=/path/to/testcase --output_dir=/tmp/out --input_mutator=inf_radamsa_spliced
```

There are many mutators. Some of the mutators are deterministic, and therefore run for a period of time that is proportional to the number of `receive` system calls in the input testcase. Other mutators are non-deterministic and can run forever. These mutators are prefixed with `inf_`.
31 changes: 31 additions & 0 deletions coverage.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Copyright 2015 Peter Goodman ([email protected]), all rights reserved. */

#include <gflags/gflags.h>

#include <iostream>

#include "granary/code/index.h"

DEFINE_bool(persist, true, "Should the code cache be persisted?");

DEFINE_string(persist_dir, "", "Directory path to where runtime state should "
"be persisted. This should be unique for a "
"given set of binaries.");

extern "C" int main(int argc, char **argv, char **) {
using namespace granary;
gflags::SetUsageMessage(std::string(argv[0]) + " [options]");
gflags::ParseCommandLineFlags(&argc, &argv, false);

if (FLAGS_persist_dir.empty()) {
std::cerr << "Must provide a unique path to a directory where the "
<< "runtime state can be persisted." << std::endl;
return EXIT_FAILURE;
}

index::Init();

index::Dump();

return EXIT_SUCCESS;
}
16 changes: 16 additions & 0 deletions granary/arch/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Copyright 2015 Peter Goodman, all rights reserved. */


#ifndef GRANARY_ARCH_BASE_H_
#define GRANARY_ARCH_BASE_H_

namespace granary {
namespace arch {

void Init(void);
void Exit(void);

} // namespace arch
} // namespace granary

#endif // GRANARY_ARCH_BASE_H_
16 changes: 16 additions & 0 deletions granary/arch/cpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Copyright 2015 Peter Goodman, all rights reserved. */

#ifndef GRANARY_ARCH_CPU_H_
#define GRANARY_ARCH_CPU_H_

namespace granary {
namespace arch {

void Relax(void);

void SerializePipeline(void);

} // namespace arch
} // namespace granary

#endif // GRANARY_ARCH_CPU_H_
25 changes: 25 additions & 0 deletions granary/arch/fault.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Copyright 2016 Peter Goodman ([email protected]), all rights reserved. */

#ifndef GRANARY_ARCH_FAULT_H_
#define GRANARY_ARCH_FAULT_H_

#include "granary/base/base.h"

namespace granary {
namespace os {
class Process32;
} // namespace os
namespace arch {

void DecomposeFaultAddr(
const os::Process32 *process,
Addr32 *base,
Addr32 *index,
Addr32 *scale,
Addr32 *disp,
Addr32 fault_addr);

} // namespace arch
} // namespace granary

#endif // GRANARY_ARCH_FAULT_H_
32 changes: 32 additions & 0 deletions granary/arch/instruction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* Copyright 2015 Peter Goodman, all rights reserved. */

#ifndef GRANARY_ARCH_INSTRUCTION_H_
#define GRANARY_ARCH_INSTRUCTION_H_

#include "granary/arch/x86/instruction.h"

#include <forward_list>

namespace granary {
namespace arch {

// Used to allocate instructions in the REVERSE of the order that they
// will be encoded.
class InstructionStack : public std::forward_list<arch::Instruction> {
public:
inline Instruction *Add(void) {
Instruction instr;
memset(&instr, 0, sizeof instr);
auto item = this->emplace_after(this->before_begin());
return &*item;
}

inline void Reset(void) {
this->clear();
}
};

} // namespace arch
} // namespace granary

#endif // GRANARY_ARCH_INSTRUCTION_H_
Loading

0 comments on commit 21040a5

Please sign in to comment.