Compare commits

..

No commits in common. "2ea67d617477481bdd923e03cf4bef41c831ac8a" and "1dbf12c728740b67eaa46b473785d5f0273a9d49" have entirely different histories.

7 changed files with 558 additions and 588 deletions

View File

@ -1,78 +0,0 @@
# Generated from CLion C/C++ Code Style settings
BinPackParameters: false
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignArrayOfStructures: Left
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignOperands: DontAlign
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
# 函数和返回类型分两行,方便阅读
AlwaysBreakAfterReturnType: TopLevelDefinitions
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
BreakInheritanceList: BeforeColon
ColumnLimit: 120
CompactNamespaces: false
ContinuationIndentWidth: 4
EmptyLineBeforeAccessModifier: LogicalBlock
SeparateDefinitionBlocks: Always
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PointerAlignment: Right
ReflowComments: false
SortIncludes: CaseSensitive
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never
PenaltyIndentedWhitespace: 1

View File

@ -4,7 +4,7 @@ LDIR=lib
BUILD=obj
ODIR=src/.obj
CFLAGS=-I$(IDIR) -O3 #-ggdb
CFLAGS=-I$(IDIR) #-ggdb
# CXX=g++
LDFLAGS=

View File

@ -1,5 +1,6 @@
#include "unistd.h"
#include "utils.h"
#include "unistd.h"
typedef struct {
char* v_addr;
@ -9,4 +10,5 @@ typedef struct {
//----------------------------------------------------------
// Functions
void rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size, char* o_file, uint64_t flags);

View File

@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdio.h>
#define BIT(x) (1ULL<<(x))
#define KB(x) ((x)<<10ULL)
#define MB(x) ((x)<<20ULL)
@ -10,6 +11,7 @@
#define CL_SHIFT 6
#define CL_SIZE 64
#define F_CLEAR 0L
#define F_VERBOSE BIT(0)
#define F_EXPORT BIT(1)
@ -21,56 +23,66 @@
#define F_ALLOC_HUGE_2M F_ALLOC_HUGE | BIT(MEM_SHIFT+2)
#define F_POPULATE BIT(MEM_SHIFT+3)
//----------------------------------------------------------
// Static functions
static inline __attribute__((always_inline)) void
clflush(volatile void *p)
static inline __attribute__((always_inline)) void clflush(volatile void *p)
{
asm volatile("clflush (%0)\n" ::"r"(p) : "memory");
asm volatile("clflush (%0)\n"
:: "r" (p) : "memory");
}
static inline __attribute__((always_inline)) void
mfence()
static inline __attribute__((always_inline)) void mfence()
{
asm volatile ("mfence" : : : "memory");
}
static inline __attribute__((always_inline)) void
lfence()
static inline __attribute__((always_inline)) void lfence()
{
asm volatile ("lfence" : : : "memory");
}
static inline __attribute__((always_inline)) uint64_t
rdtscp(void)
static inline __attribute__((always_inline)) uint64_t rdtscp(void)
{
uint64_t lo, hi;
asm volatile("rdtscp\n" : "=a"(lo), "=d"(hi)::"%rcx");
asm volatile("rdtscp\n"
: "=a" (lo), "=d" (hi)
:: "%rcx");
return (hi << 32) | lo;
}
static inline __attribute__((always_inline)) uint64_t
rdtsc(void)
static inline __attribute__((always_inline)) uint64_t rdtsc(void)
{
uint64_t lo, hi;
asm volatile("rdtsc\n" : "=a"(lo), "=d"(hi)::"%rcx");
asm volatile("rdtsc\n"
: "=a" (lo), "=d" (hi)
:: "%rcx");
return (hi << 32) | lo;
}
//----------------------------------------------------------
// Memory alloc
typedef struct {
char* buffer;
uint64_t size;
uint64_t flags;
} mem_buff_t;
int alloc_buffer(mem_buff_t* mem);
int free_buffer(mem_buff_t* mem);
//----------------------------------------------------------
// Helpers
int gt(const void * a, const void * b);
@ -80,3 +92,4 @@ double mean(uint64_t *vals, size_t size);
uint64_t median(uint64_t* vals, size_t size);
char* bit_string(uint64_t val);

View File

@ -1,21 +1,22 @@
#include "stdio.h"
// #include <x86intrin.h> /* for rdtsc, rdtscp, clflush */
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <sched.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <time.h>
#include <sched.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>
#include <getopt.h>
#include "rev-mc.h"
#include "utils.h"
#include "rev-mc.h"
#define SETS_std (2*16) // 1rk-1ch
#define ROUNDS_std 1000
@ -23,34 +24,38 @@
#define MEM_SIZE_std GB(5L)
#define O_FILE_std "access.csv"
#define FIELDS "base,probe,rounds,time"
//-----------------------------------------------
// GLOBALS
//-----------------------------------------------
void
print_usage()
{
fprintf(stderr,
"[ LOG ] - Usage ./test [-h] [-s sets] [-r rounds] [-t threshold] [-o o_file] [-v] [--mem mem_size]\n");
void print_usage() {
fprintf(stderr, "[ LOG ] - Usage ./test [-h] [-s sets] [-r rounds] [-t threshold] [-o o_file] [-v] [--mem mem_size]\n");
fprintf(stderr, " -h = this help message\n");
fprintf(stderr, " -s sets = number of expected sets (default: %d)\n", SETS_std);
fprintf(stderr, " -r rounds = number of rounds per tuple (default: %d)\n",
ROUNDS_std);
fprintf(stderr, " -t threshold = time threshold for conflicts (default: %d)\n",
THRESHOLD_std);
fprintf(stderr, " -o o_file = output file for mem profiling (default: %s)\n",
O_FILE_std);
fprintf(stderr, " --mem mem_size = allocation size (default: %ld)\n",
(uint64_t) MEM_SIZE_std);
fprintf(stderr, " -r rounds = number of rounds per tuple (default: %d)\n", ROUNDS_std);
fprintf(stderr, " -t threshold = time threshold for conflicts (default: %d)\n", THRESHOLD_std);
fprintf(stderr, " -o o_file = output file for mem profiling (default: %s)\n", O_FILE_std);
fprintf(stderr, " --mem mem_size = allocation size (default: %ld)\n", (uint64_t) MEM_SIZE_std);
fprintf(stderr, " -v = verbose\n\n");
}
//-----------------------------------------------
int
main(int argc, char **argv)
{
int main(int argc, char** argv) {
uint64_t flags = 0ULL;
size_t sets_cnt = SETS_std;
@ -69,14 +74,17 @@ main(int argc, char **argv)
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
static struct option long_options[] =
{
/* These options set a flag. */
{"mem", required_argument, 0, 0},
{0, 0, 0, 0}
};
int arg = getopt_long(argc, argv, "o:s:r:t:hv", long_options, &option_index);
int arg = getopt_long (argc, argv, "o:s:r:t:hv",
long_options, &option_index);
if (arg == -1) break;
if (arg == -1)
break;
switch(arg) {
case 0:
@ -109,11 +117,18 @@ main(int argc, char **argv)
default:
print_usage();
return 0;
}
}
rev_mc(sets_cnt, threshold, rounds, m_size, o_file, flags);
return 0;
}
/*I'm refactoring the set struct to add also timing in there. */

View File

@ -19,7 +19,8 @@
#define BOOL_XOR(a, b) ((a) != (b))
#define O_HEADER "base,probe,time\n"
#define ALIGN_TO(X, Y) ((X) & (~((1LL << (Y)) - 1LL)))// Mask out the lower Y bits
#define ALIGN_TO(X, Y) \
((X) & (~((1LL << (Y)) - 1LL))) // Mask out the lower Y bits
#define LS_BITMASK(X) ((1LL << (X)) - 1LL) // Mask only the lower X bits
#define SET_SIZE 40 // elements per set
@ -32,7 +33,9 @@
// https://stackoverflow.com/questions/1644868/define-macro-for-debug-printing-in-c
#define verbose_printerr(fmt, ...) \
do { \
if (flags & F_VERBOSE) { fprintf(stderr, fmt, ##__VA_ARGS__); } \
if (flags & F_VERBOSE) { \
fprintf(stderr, fmt, ##__VA_ARGS__); \
} \
} while (0)
typedef std::vector<addr_tuple> set_t;
@ -49,13 +52,11 @@ void verify_sets(std::vector<set_t> &sets, uint64_t threshold, size_t rounds);
#pragma push_options
#pragma optimize("O0")
static std::vector<uint64_t> time_vals;
uint64_t
time_tuple(volatile char *a1, volatile char *a2, size_t rounds)
{
uint64_t time_tuple(volatile char *a1, volatile char *a2, size_t rounds) {
// uint64_t* time_vals = (uint64_t*) calloc(rounds, sizeof(uint64_t));
if (rounds > time_vals.size()) time_vals.resize(rounds);
if (rounds > time_vals.size())
time_vals.resize(rounds);
uint64_t t0;
sched_yield();
@ -74,27 +75,19 @@ time_tuple(volatile char *a1, volatile char *a2, size_t rounds)
// free(time_vals);
return mdn;
}
#pragma pop_options
//----------------------------------------------------------
char *
get_rnd_addr(char *base, size_t m_size, size_t align)
{
return (char *) ALIGN_TO((uint64_t) base, (uint64_t) align) + ALIGN_TO(rand() % m_size, (uint64_t) align);
char *get_rnd_addr(char *base, size_t m_size, size_t align) {
return (char *)ALIGN_TO((uint64_t)base, (uint64_t)align) +
ALIGN_TO(rand() % m_size, (uint64_t)align);
}
//----------------------------------------------------------
uint64_t
get_pfn(uint64_t entry)
{
return ((entry) & 0x3fffffffffffff);
}
uint64_t get_pfn(uint64_t entry) { return ((entry) & 0x3fffffffffffff); }
//----------------------------------------------------------
uint64_t
get_phys_addr(uint64_t v_addr)
{
uint64_t get_phys_addr(uint64_t v_addr) {
uint64_t entry;
uint64_t offset = (v_addr / 4096) * sizeof(entry);
uint64_t pfn;
@ -110,9 +103,7 @@ get_phys_addr(uint64_t v_addr)
}
//----------------------------------------------------------
addr_tuple
gen_addr_tuple(char *v_addr)
{
addr_tuple gen_addr_tuple(char *v_addr) {
return (addr_tuple){v_addr, get_phys_addr((uint64_t)v_addr)};
}
@ -120,9 +111,7 @@ gen_addr_tuple(char *v_addr)
// https://www.cs.umd.edu/~gasarch/TOPICS/factoring/fastgauss.pdf
// gaussian elimination in GF2
std::vector<uint64_t>
reduce_masks(std::vector<uint64_t> masks)
{
std::vector<uint64_t> reduce_masks(std::vector<uint64_t> masks) {
size_t height, width, height_t, width_t;
@ -141,11 +130,15 @@ reduce_masks(std::vector<uint64_t> masks)
std::vector<uint64_t> filtered_masks;
for (size_t i = 0; i < height; i++) {
for (size_t j = 0; j < width; j++) { mtx[i][width - j - 1] = (masks[i] & (1ULL << (j))); }
for (size_t j = 0; j < width; j++) {
mtx[i][width - j - 1] = (masks[i] & (1ULL << (j)));
}
}
for (size_t i = 0; i < height; i++) {
for (size_t j = 0; j < width; j++) { mtx_t[j][i] = mtx[i][j]; }
for (size_t j = 0; j < width; j++) {
mtx_t[j][i] = mtx[i][j];
}
}
int64_t pvt_col = 0;
@ -155,11 +148,15 @@ reduce_masks(std::vector<uint64_t> masks)
if (mtx_t[row][pvt_col]) {
filtered_masks.push_back(masks[pvt_col]);
for (size_t c = 0; c < width_t; c++) {
if (c == pvt_col) continue;
if (!(mtx_t[row][c])) continue;
if (c == pvt_col)
continue;
if (!(mtx_t[row][c]))
continue;
// column sum
for (size_t r = 0; r < height_t; r++) { mtx_t[r][c] = BOOL_XOR(mtx_t[r][c], mtx_t[r][pvt_col]); }
for (size_t r = 0; r < height_t; r++) {
mtx_t[r][c] = BOOL_XOR(mtx_t[r][c], mtx_t[r][pvt_col]);
}
}
break;
}
@ -172,23 +169,23 @@ reduce_masks(std::vector<uint64_t> masks)
//----------------------------------------------------------
// from https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
uint64_t
next_bit_permutation(uint64_t v)
{
uint64_t next_bit_permutation(uint64_t v) {
uint64_t t = v | (v - 1);
return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzl(v) + 1));
}
//----------------------------------------------------------
std::vector<uint64_t>
find_functions(std::vector<set_t> sets, size_t max_fn_bits, size_t msb, uint64_t flags)
{
std::vector<uint64_t> find_functions(std::vector<set_t> sets,
size_t max_fn_bits, size_t msb,
uint64_t flags) {
std::vector<uint64_t> masks;
verbose_printerr("~~~~~~~~~~ Candidate functions ~~~~~~~~~~\n");
for (size_t bits = 1L; bits <= max_fn_bits; bits++) {
uint64_t fn_mask = ((1L << (bits)) - 1);// avoid the first 6 bits since they are the cacheline bits
uint64_t fn_mask =
((1L << (bits)) -
1); // avoid the first 6 bits since they are the cacheline bits
uint64_t last_mask = (fn_mask << (msb - bits));
fn_mask <<= CL_SHIFT;
verbose_printerr("[ LOG ] - #Bits: %ld \n", bits);
@ -203,10 +200,13 @@ find_functions(std::vector<set_t> sets, size_t max_fn_bits, size_t msb, uint64_t
for (size_t i = 1; i < curr_set.size(); i++) {
uint64_t res_base = __builtin_parityl(curr_set[0].p_addr & fn_mask);
uint64_t res_probe = __builtin_parityl(curr_set[i].p_addr & fn_mask);
if (res_base != res_probe) { goto next_mask; }
if (res_base != res_probe) {
goto next_mask;
}
}
verbose_printerr("\t Candidate: 0x%0lx \t\t bits: %s\n", fn_mask, bit_string(fn_mask));
}
verbose_printerr("\t Candidate: 0x%0lx \t\t bits: %s\n", fn_mask,
bit_string(fn_mask));
masks.push_back(fn_mask);
next_mask:
@ -216,18 +216,22 @@ find_functions(std::vector<set_t> sets, size_t max_fn_bits, size_t msb, uint64_t
verbose_printerr("~~~~~~~~~~ Found Functions ~~~~~~~~~~\n");
masks = reduce_masks(masks);
if (flags & F_VERBOSE) {
for (auto m : masks) { fprintf(stderr, "\t Valid Function: 0x%0lx \t\t bits: %s\n", m, bit_string(m)); }
for (auto m : masks) {
fprintf(stderr, "\t Valid Function: 0x%0lx \t\t bits: %s\n", m,
bit_string(m));
}
}
for (auto m : masks) {
fprintf(stdout, "0x%lx\n", m);
}
for (auto m : masks) { fprintf(stdout, "0x%lx\n", m); }
return masks;
}
std::vector<int>
find_set_bits(uint64_t val)
{
std::vector<int> find_set_bits(uint64_t val) {
std::vector<int> set_bits;
for (int i = 0; i < 64; i++) {
if (!(val & (1ULL << i))) continue;
if (!(val & (1ULL << i)))
continue;
set_bits.push_back(i);
}
@ -235,11 +239,12 @@ find_set_bits(uint64_t val)
}
//----------------------------------------------------------
std::vector<uint8_t>
get_dram_fn(uint64_t addr, std::vector<uint64_t> fn_masks)
{
std::vector<uint8_t> get_dram_fn(uint64_t addr,
std::vector<uint64_t> fn_masks) {
std::vector<uint8_t> addr_dram;
for (auto fn : fn_masks) { addr_dram.push_back(__builtin_parityl(addr & fn)); }
for (auto fn : fn_masks) {
addr_dram.push_back(__builtin_parityl(addr & fn));
}
return addr_dram;
}
@ -249,13 +254,8 @@ It currently finds some of the interesting bits for the row addressing.
@TODO still need to figure out which bits are used for the row addressing and
which are from the bank selection. This is currently done manually
*/
uint64_t
find_row_mask(std::vector<set_t> &sets,
std::vector<uint64_t> fn_masks,
mem_buff_t mem,
uint64_t threshold,
uint64_t flags)
{
uint64_t find_row_mask(std::vector<set_t> &sets, std::vector<uint64_t> fn_masks,
mem_buff_t mem, uint64_t threshold, uint64_t flags) {
addr_tuple base_addr = gen_addr_tuple(get_rnd_addr(mem.buffer, mem.size, 0));
std::vector<set_t> same_row_sets;
@ -265,19 +265,24 @@ find_row_mask(std::vector<set_t> &sets,
for (int i = 0; i < 2; i++) {
verbose_printerr("[LOG] - Set #%d\n", i);
addr_tuple base_addr = sets[i][0];
std::vector<uint8_t> base_dram = get_dram_fn((uint64_t) base_addr.p_addr, fn_masks);
std::vector<uint8_t> base_dram =
get_dram_fn((uint64_t)base_addr.p_addr, fn_masks);
same_row_sets.push_back({base_addr});
uint64_t cnt = 0;
while (cnt < ROW_SET_CNT) {
addr_tuple tmp = gen_addr_tuple(get_rnd_addr(mem.buffer, mem.size, 0));
if (get_dram_fn((uint64_t) tmp.p_addr, fn_masks) != base_dram) continue;
if (get_dram_fn((uint64_t)tmp.p_addr, fn_masks) != base_dram)
continue;
uint64_t time = time_tuple((volatile char *) base_addr.v_addr, (volatile char *) tmp.v_addr, 1000);
uint64_t time = time_tuple((volatile char *)base_addr.v_addr,
(volatile char *)tmp.v_addr, 1000);
if (time > threshold) continue;
if (time > threshold)
continue;
verbose_printerr("[LOG] - %lx - %lx\t Time: %ld <== GOTCHA\n", base_addr.p_addr, tmp.p_addr, time);
verbose_printerr("[LOG] - %lx - %lx\t Time: %ld <== GOTCHA\n",
base_addr.p_addr, tmp.p_addr, time);
same_row_sets[i].push_back(tmp);
cnt++;
@ -286,7 +291,8 @@ find_row_mask(std::vector<set_t> &sets,
uint64_t row_mask = LS_BITMASK(16); // use 16 bits for the row
uint64_t last_mask = (row_mask << (40 - 16));
row_mask <<= CL_SHIFT;// skip the lowest 6 bits since they're used for CL addressing
row_mask <<=
CL_SHIFT; // skip the lowest 6 bits since they're used for CL addressing
while (row_mask < last_mask) {
if (row_mask & LS_BITMASK(CL_SHIFT)) {
@ -298,7 +304,9 @@ find_row_mask(std::vector<set_t> &sets,
addr_tuple base_addr = addr_pool[0];
for (int i = 1; i < addr_pool.size(); i++) {
addr_tuple tmp = addr_pool[i];
if ((tmp.p_addr & row_mask) != (base_addr.p_addr & row_mask)) { goto next_mask; }
if ((tmp.p_addr & row_mask) != (base_addr.p_addr & row_mask)) {
goto next_mask;
}
}
}
@ -311,17 +319,19 @@ find_row_mask(std::vector<set_t> &sets,
// super hackish way to recover the real row mask
for (auto m : fn_masks) {
uint64_t lsb = (1 << (__builtin_ctzl(m) + 1));
if (lsb & row_mask) { row_mask ^= (1 << __builtin_ctzl(m)); }
if (lsb & row_mask) {
row_mask ^= (1 << __builtin_ctzl(m));
}
verbose_printerr("[LOG] - Row mask: 0x%0lx \t\t bits: %s\n", row_mask, bit_string(row_mask));
}
verbose_printerr("[LOG] - Row mask: 0x%0lx \t\t bits: %s\n", row_mask,
bit_string(row_mask));
printf("0x%lx\n", row_mask);
return row_mask;
}
//----------------------------------------------------------
void
rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size, char *o_file, uint64_t flags)
{
void rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size,
char *o_file, uint64_t flags) {
time_t t;
@ -356,7 +366,8 @@ rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size, char *o_
while (!found_enough(sets, sets_cnt, SET_SIZE)) {
char *rnd_addr = get_rnd_addr(mem.buffer, mem.size, CL_SHIFT);
if (is_in(rnd_addr, used_addr)) continue;
if (is_in(rnd_addr, used_addr))
continue;
// used_addr.push_back(rnd_addr);
used_addr.insert(rnd_addr);
@ -366,11 +377,15 @@ rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size, char *o_
for (size_t idx = 0; idx < sets.size(); idx++) {
uint64_t time = 0;
addr_tuple tmp = sets[idx][0];
time = time_tuple((volatile char *) tmp.v_addr, (volatile char *) tp.v_addr, rounds);
if (flags & F_EXPORT) { dprintf(o_fd, "%lx,%lx,%ld\n", (uint64_t) tp.v_addr, (uint64_t) tmp.v_addr, time); }
time = time_tuple((volatile char *)tmp.v_addr, (volatile char *)tp.v_addr,
rounds);
if (flags & F_EXPORT) {
dprintf(o_fd, "%lx,%lx,%ld\n", (uint64_t)tp.v_addr,
(uint64_t)tmp.v_addr, time);
}
if (time > threshold) {
verbose_printerr("[LOG] - [%ld] Set: %03ld -\t %lx - %lx\t Time: %ld\n", used_addr.size(), idx,
tp.p_addr, tmp.p_addr, time);
verbose_printerr("[LOG] - [%ld] Set: %03ld -\t %lx - %lx\t Time: %ld\n",
used_addr.size(), idx, tp.p_addr, tmp.p_addr, time);
sets[idx].push_back(tp);
found_set = true;
break;
@ -387,16 +402,17 @@ rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size, char *o_
filter_sets(sets, SET_SIZE);
#ifdef DEBUG_SETS
fprintf(stderr, "[ LOG ] - Cleansing sets. This may take a while... stay put\n");
fprintf(stderr,
"[ LOG ] - Cleansing sets. This may take a while... stay put\n");
verify_sets(sets, threshold, rounds);
fprintf(stderr, "[ LOG ] - Done\n");
#endif
if (flags & F_VERBOSE) { print_sets(sets); }
if (flags & F_VERBOSE) {
print_sets(sets);
}
fprintf(stderr, "Start Find Function\n");
fn_masks = find_functions(sets, 6, 30, flags);
fprintf(stderr, "Start Find RowMask\n");
uint64_t row_mask = find_row_mask(sets, fn_masks, mem, threshold, flags);
free_buffer(&mem);
@ -407,81 +423,80 @@ rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size, char *o_
//----------------------------------------------------------
// Helpers
bool
is_in(char *val, std::set<char *> arr)
{
bool is_in(char *val, std::set<char *> arr) {
return arr.find(val) != arr.end();
}
bool
is_in(char *val, std::vector<char *> arr)
{
bool is_in(char *val, std::vector<char *> arr) {
for (auto v : arr) {
if (val == v) { return true; }
if (val == v) {
return true;
}
}
return false;
}
//----------------------------------------------------------
bool
found_enough(std::vector<set_t> sets, uint64_t set_cnt, size_t set_size)
{
bool found_enough(std::vector<set_t> sets, uint64_t set_cnt, size_t set_size) {
size_t found_sets = 0;
for (int i = 0; i < sets.size(); i++) {
set_t curr_set = sets[i];
if (curr_set.size() > set_size) { found_sets += 1; }
if (curr_set.size() > set_size) {
found_sets += 1;
}
}
if (found_sets > set_cnt) {
fprintf(stderr, "[ERROR] - Found too many sets. Is %ld the correct number of sets?\n", set_cnt);
fprintf(
stderr,
"[ERROR] - Found too many sets. Is %ld the correct number of sets?\n",
set_cnt);
exit(1);
}
return (found_sets >= (set_cnt * SET_THRESH)) ? true : false;
}
void
filter_sets(std::vector<set_t> &sets, size_t set_size)
{
void filter_sets(std::vector<set_t> &sets, size_t set_size) {
for (auto s = sets.begin(); s < sets.end();) {
for (auto s = sets.begin(); s < sets.end(); s++) {
if (s->size() < set_size) {
s = sets.erase(s);
// s -= 1;
} else {
++s;
sets.erase(s);
s -= 1;
}
}
}
void
print_sets(std::vector<set_t> sets)
{
void print_sets(std::vector<set_t> sets) {
for (int idx = 0; idx < sets.size(); idx++) {
fprintf(stderr, "[LOG] - Set: %d\tSize: %ld\n", idx, sets[idx].size());
for (auto tmp : sets[idx]) { fprintf(stderr, "\tv_addr:%p - p_addr:%p\n", tmp.v_addr, (void *) tmp.p_addr); }
for (auto tmp : sets[idx]) {
fprintf(stderr, "\tv_addr:%p - p_addr:%p\n", tmp.v_addr,
(void *)tmp.p_addr);
}
}
}
#ifdef DEBUG_SETS
void
verify_sets(std::vector<set_t> &sets, uint64_t threshold, size_t rounds)
{
void verify_sets(std::vector<set_t> &sets, uint64_t threshold, size_t rounds) {
for (auto s : sets) {
// test every address against all the addresses in the set
for (auto tp_base = s.begin(); tp_base < s.end(); tp_base++) {
uint64_t conflicts = 0;
for (auto tp_probe = s.begin(); tp_probe < s.end(); tp_probe++) {
if (tp_base == tp_probe) continue;
if (tp_base == tp_probe)
continue;
uint64_t time =
time_tuple((volatile char *) tp_base->v_addr, (volatile char *) tp_probe->v_addr, rounds);
if (time > threshold) { conflicts += 1; }
uint64_t time = time_tuple((volatile char *)tp_base->v_addr,
(volatile char *)tp_probe->v_addr, rounds);
if (time > threshold) {
conflicts += 1;
}
}
if (!(conflicts > VALID_THRESH * s.size())) {
fprintf(stderr, "[ LOG ] - Removing: %p\n", tp_base->v_addr);

View File

@ -1,23 +1,24 @@
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include "utils.h"
//-----------------------------------------------
// Memory alloc
int
alloc_buffer(mem_buff_t *mem)
{
if (mem->buffer != NULL) { fprintf(stderr, "[ERROR] - Memory already allocated\n"); }
int alloc_buffer(mem_buff_t* mem) {
if (mem->buffer != NULL) {
fprintf(stderr, "[ERROR] - Memory already allocated\n");
}
uint64_t alloc_flags = MAP_PRIVATE | MAP_POPULATE | MAP_ANONYMOUS;
@ -34,47 +35,49 @@ alloc_buffer(mem_buff_t *mem)
fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
return 0;
}
int
free_buffer(mem_buff_t *mem)
{
int free_buffer(mem_buff_t* mem) {
return munmap(mem->buffer, mem->size);
}
//-----------------------------------------------
// Helpers
double
mean(uint64_t *vals, size_t size)
{
double mean(uint64_t* vals, size_t size) {
uint64_t avg = 0;
for (size_t i = 0; i < size; i++) { avg += vals[i]; }
for (size_t i = 0; i < size; i++) {
avg += vals[i];
}
return ((double)avg) / size;
}
int
gt(const void *a, const void *b)
{
int gt(const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
uint64_t
median(uint64_t *vals, size_t size)
{
uint64_t median(uint64_t* vals, size_t size) {
qsort(vals, size, sizeof(uint64_t), gt);
return ((size%2)==0) ? vals[size/2] : (vals[(size_t)size/2]+vals[((size_t)size/2+1)])/2;
}
char *
bit_string(uint64_t val)
{
char* bit_string(uint64_t val) {
static char bit_str[256];
char itoa_str[8];
strcpy(bit_str, "");
for (int shift = 0; shift < 64; shift++) {
if ((val >> shift) & 1) {
if (strcmp(bit_str, "") != 0) { strcat(bit_str, "+ "); }
if (strcmp(bit_str, "") != 0) {
strcat(bit_str, "+ ");
}
sprintf(itoa_str, "%d ", shift);
strcat(bit_str, itoa_str);
}