feat: format code
This commit is contained in:
parent
1dbf12c728
commit
c7227f88b6
78
.clang-format
Normal file
78
.clang-format
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# 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
|
@ -1,14 +1,12 @@
|
|||||||
#include "utils.h"
|
|
||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* v_addr;
|
char *v_addr;
|
||||||
uint64_t p_addr;
|
uint64_t p_addr;
|
||||||
} addr_tuple;
|
} addr_tuple;
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
|
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);
|
|
||||||
|
@ -1,95 +1,82 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define BIT(x) (1ULL << (x))
|
||||||
#define BIT(x) (1ULL<<(x))
|
#define KB(x) ((x) << 10ULL)
|
||||||
#define KB(x) ((x)<<10ULL)
|
#define MB(x) ((x) << 20ULL)
|
||||||
#define MB(x) ((x)<<20ULL)
|
#define GB(x) ((x) << 30ULL)
|
||||||
#define GB(x) ((x)<<30ULL)
|
|
||||||
#define CL_SHIFT 6
|
#define CL_SHIFT 6
|
||||||
#define CL_SIZE 64
|
#define CL_SIZE 64
|
||||||
|
|
||||||
|
#define F_CLEAR 0L
|
||||||
|
#define F_VERBOSE BIT(0)
|
||||||
|
#define F_EXPORT BIT(1)
|
||||||
|
|
||||||
#define F_CLEAR 0L
|
#define MEM_SHIFT (30L)
|
||||||
#define F_VERBOSE BIT(0)
|
#define MEM_MASK 0b11111ULL << MEM_SHIFT
|
||||||
#define F_EXPORT BIT(1)
|
#define F_ALLOC_HUGE BIT(MEM_SHIFT)
|
||||||
|
#define F_ALLOC_HUGE_1G F_ALLOC_HUGE | BIT(MEM_SHIFT + 1)
|
||||||
#define MEM_SHIFT (30L)
|
#define F_ALLOC_HUGE_2M F_ALLOC_HUGE | BIT(MEM_SHIFT + 2)
|
||||||
#define MEM_MASK 0b11111ULL << MEM_SHIFT
|
#define F_POPULATE BIT(MEM_SHIFT + 3)
|
||||||
#define F_ALLOC_HUGE BIT(MEM_SHIFT)
|
|
||||||
#define F_ALLOC_HUGE_1G F_ALLOC_HUGE | BIT(MEM_SHIFT+1)
|
|
||||||
#define F_ALLOC_HUGE_2M F_ALLOC_HUGE | BIT(MEM_SHIFT+2)
|
|
||||||
#define F_POPULATE BIT(MEM_SHIFT+3)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Static functions
|
// 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"
|
asm volatile("clflush (%0)\n" ::"r"(p) : "memory");
|
||||||
:: "r" (p) : "memory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline)) void
|
||||||
static inline __attribute__((always_inline)) void mfence()
|
mfence()
|
||||||
{
|
{
|
||||||
asm volatile ("mfence" : : : "memory");
|
asm volatile("mfence" : : : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline)) void
|
||||||
static inline __attribute__((always_inline)) void lfence()
|
lfence()
|
||||||
{
|
{
|
||||||
asm volatile ("lfence" : : : "memory");
|
asm volatile("lfence" : : : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline)) uint64_t
|
||||||
static inline __attribute__((always_inline)) uint64_t rdtscp(void)
|
rdtscp(void)
|
||||||
{
|
{
|
||||||
uint64_t lo, hi;
|
uint64_t lo, hi;
|
||||||
asm volatile("rdtscp\n"
|
asm volatile("rdtscp\n" : "=a"(lo), "=d"(hi)::"%rcx");
|
||||||
: "=a" (lo), "=d" (hi)
|
return (hi << 32) | lo;
|
||||||
:: "%rcx");
|
|
||||||
return (hi << 32) | lo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline)) uint64_t
|
||||||
static inline __attribute__((always_inline)) uint64_t rdtsc(void)
|
rdtsc(void)
|
||||||
{
|
{
|
||||||
uint64_t lo, hi;
|
uint64_t lo, hi;
|
||||||
asm volatile("rdtsc\n"
|
asm volatile("rdtsc\n" : "=a"(lo), "=d"(hi)::"%rcx");
|
||||||
: "=a" (lo), "=d" (hi)
|
return (hi << 32) | lo;
|
||||||
:: "%rcx");
|
|
||||||
return (hi << 32) | lo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Memory alloc
|
// Memory alloc
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* buffer;
|
char *buffer;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
} mem_buff_t;
|
} mem_buff_t;
|
||||||
|
|
||||||
|
int alloc_buffer(mem_buff_t *mem);
|
||||||
|
|
||||||
int alloc_buffer(mem_buff_t* mem);
|
int free_buffer(mem_buff_t *mem);
|
||||||
|
|
||||||
int free_buffer(mem_buff_t* mem);
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
int gt(const void * a, const void * b);
|
int gt(const void *a, const void *b);
|
||||||
|
|
||||||
double mean(uint64_t* vals, size_t size);
|
double mean(uint64_t *vals, size_t size);
|
||||||
|
|
||||||
uint64_t median(uint64_t* vals, size_t size);
|
uint64_t median(uint64_t *vals, size_t size);
|
||||||
|
|
||||||
char* bit_string(uint64_t val);
|
|
||||||
|
|
||||||
|
char *bit_string(uint64_t val);
|
||||||
|
171
drama/src/main.c
171
drama/src/main.c
@ -1,134 +1,119 @@
|
|||||||
|
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
// #include <x86intrin.h> /* for rdtsc, rdtscp, clflush */
|
// #include <x86intrin.h> /* for rdtsc, rdtscp, clflush */
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.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 <fcntl.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "rev-mc.h"
|
#include "rev-mc.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SETS_std (2 * 16)// 1rk-1ch
|
||||||
#define SETS_std (2*16) // 1rk-1ch
|
#define ROUNDS_std 1000
|
||||||
#define ROUNDS_std 1000
|
#define THRESHOLD_std 340
|
||||||
#define THRESHOLD_std 340
|
#define MEM_SIZE_std GB(5L)
|
||||||
#define MEM_SIZE_std GB(5L)
|
#define O_FILE_std "access.csv"
|
||||||
#define O_FILE_std "access.csv"
|
|
||||||
|
|
||||||
|
|
||||||
#define FIELDS "base,probe,rounds,time"
|
#define FIELDS "base,probe,rounds,time"
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
// GLOBALS
|
// GLOBALS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
void print_usage() {
|
void
|
||||||
fprintf(stderr, "[ LOG ] - Usage ./test [-h] [-s sets] [-r rounds] [-t threshold] [-o o_file] [-v] [--mem mem_size]\n");
|
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, " -h = this help message\n");
|
||||||
fprintf(stderr, " -s sets = number of expected sets (default: %d)\n", SETS_std);
|
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, " -r rounds = number of rounds per tuple (default: %d)\n",
|
||||||
fprintf(stderr, " -t threshold = time threshold for conflicts (default: %d)\n", THRESHOLD_std);
|
ROUNDS_std);
|
||||||
fprintf(stderr, " -o o_file = output file for mem profiling (default: %s)\n", O_FILE_std);
|
fprintf(stderr, " -t threshold = time threshold for conflicts (default: %d)\n",
|
||||||
fprintf(stderr, " --mem mem_size = allocation size (default: %ld)\n", (uint64_t) MEM_SIZE_std);
|
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");
|
fprintf(stderr, " -v = verbose\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
int main(int argc, char** argv) {
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
uint64_t flags = 0ULL;
|
uint64_t flags = 0ULL;
|
||||||
size_t sets_cnt = SETS_std;
|
size_t sets_cnt = SETS_std;
|
||||||
size_t rounds = ROUNDS_std;
|
size_t rounds = ROUNDS_std;
|
||||||
size_t m_size = MEM_SIZE_std;
|
size_t m_size = MEM_SIZE_std;
|
||||||
size_t threshold = THRESHOLD_std;
|
size_t threshold = THRESHOLD_std;
|
||||||
char* o_file = (char*) O_FILE_std;
|
char *o_file = (char *) O_FILE_std;
|
||||||
|
|
||||||
flags |= F_POPULATE;
|
flags |= F_POPULATE;
|
||||||
|
|
||||||
if(geteuid() != 0) {
|
if (geteuid() != 0) {
|
||||||
fprintf(stderr, "[ERROR] - You need to run as root to access pagemap!\n");
|
fprintf(stderr, "[ERROR] - You need to run as root to access pagemap!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int this_option_optind = optind ? optind : 1;
|
int this_option_optind = optind ? optind : 1;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
static struct option long_options[] =
|
static struct option long_options[] = {
|
||||||
{
|
/* These options set a flag. */
|
||||||
/* These options set a flag. */
|
{"mem", required_argument, 0, 0},
|
||||||
{"mem", required_argument, 0, 0},
|
{0, 0, 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)
|
if (arg == -1) break;
|
||||||
break;
|
|
||||||
|
|
||||||
switch(arg) {
|
switch (arg) {
|
||||||
|
case 0:
|
||||||
|
switch (option_index) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (option_index){
|
m_size = atoi(optarg);// TODO proper parsing of this
|
||||||
case 0:
|
|
||||||
m_size = atoi(optarg); // TODO proper parsing of this
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'o':
|
|
||||||
o_file = (char*) malloc(sizeof(char)*strlen(optarg));
|
|
||||||
strncpy(o_file, optarg, strlen(optarg));
|
|
||||||
flags |= F_EXPORT;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
sets_cnt = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
rounds = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
threshold = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
flags |= F_VERBOSE;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
default:
|
default:
|
||||||
print_usage();
|
break;
|
||||||
return 0;
|
}
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
o_file = (char *) malloc(sizeof(char) * strlen(optarg));
|
||||||
|
strncpy(o_file, optarg, strlen(optarg));
|
||||||
|
flags |= F_EXPORT;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sets_cnt = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
rounds = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
threshold = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
flags |= F_VERBOSE;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
print_usage();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rev_mc(sets_cnt, threshold, rounds, m_size, o_file, flags);
|
rev_mc(sets_cnt, threshold, rounds, m_size, o_file, flags);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*I'm refactoring the set struct to add also timing in there. */
|
/*I'm refactoring the set struct to add also timing in there. */
|
||||||
|
@ -19,24 +19,21 @@
|
|||||||
|
|
||||||
#define BOOL_XOR(a, b) ((a) != (b))
|
#define BOOL_XOR(a, b) ((a) != (b))
|
||||||
#define O_HEADER "base,probe,time\n"
|
#define O_HEADER "base,probe,time\n"
|
||||||
#define ALIGN_TO(X, Y) \
|
#define ALIGN_TO(X, Y) ((X) & (~((1LL << (Y)) - 1LL)))// Mask out the lower Y bits
|
||||||
((X) & (~((1LL << (Y)) - 1LL))) // Mask out the lower Y bits
|
#define LS_BITMASK(X) ((1LL << (X)) - 1LL) // Mask only the lower X bits
|
||||||
#define LS_BITMASK(X) ((1LL << (X)) - 1LL) // Mask only the lower X bits
|
|
||||||
|
|
||||||
#define SET_SIZE 40 // elements per set
|
#define SET_SIZE 40// elements per set
|
||||||
#define VALID_THRESH 0.75f
|
#define VALID_THRESH 0.75f
|
||||||
#define SET_THRESH 0.95f
|
#define SET_THRESH 0.95f
|
||||||
#define BITSET_SIZE 256 // bitset used to exploit bitwise operations
|
#define BITSET_SIZE 256// bitset used to exploit bitwise operations
|
||||||
#define ROW_SET_CNT 5
|
#define ROW_SET_CNT 5
|
||||||
|
|
||||||
// from
|
// from
|
||||||
// https://stackoverflow.com/questions/1644868/define-macro-for-debug-printing-in-c
|
// https://stackoverflow.com/questions/1644868/define-macro-for-debug-printing-in-c
|
||||||
#define verbose_printerr(fmt, ...) \
|
#define verbose_printerr(fmt, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (flags & F_VERBOSE) { \
|
if (flags & F_VERBOSE) { fprintf(stderr, fmt, ##__VA_ARGS__); } \
|
||||||
fprintf(stderr, fmt, ##__VA_ARGS__); \
|
} while (0)
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
typedef std::vector<addr_tuple> set_t;
|
typedef std::vector<addr_tuple> set_t;
|
||||||
|
|
||||||
@ -52,200 +49,198 @@ void verify_sets(std::vector<set_t> &sets, uint64_t threshold, size_t rounds);
|
|||||||
#pragma push_options
|
#pragma push_options
|
||||||
#pragma optimize("O0")
|
#pragma optimize("O0")
|
||||||
static std::vector<uint64_t> time_vals;
|
static std::vector<uint64_t> time_vals;
|
||||||
uint64_t time_tuple(volatile char *a1, volatile char *a2, size_t rounds) {
|
|
||||||
|
|
||||||
// uint64_t* time_vals = (uint64_t*) calloc(rounds, sizeof(uint64_t));
|
uint64_t
|
||||||
if (rounds > time_vals.size())
|
time_tuple(volatile char *a1, volatile char *a2, size_t rounds)
|
||||||
time_vals.resize(rounds);
|
{
|
||||||
|
|
||||||
uint64_t t0;
|
// uint64_t* time_vals = (uint64_t*) calloc(rounds, sizeof(uint64_t));
|
||||||
sched_yield();
|
if (rounds > time_vals.size()) time_vals.resize(rounds);
|
||||||
for (size_t i = 0; i < rounds; i++) {
|
|
||||||
mfence();
|
|
||||||
t0 = rdtscp();
|
|
||||||
*a1;
|
|
||||||
*a2;
|
|
||||||
time_vals[i] = rdtscp() - t0;
|
|
||||||
lfence();
|
|
||||||
clflush(a1);
|
|
||||||
clflush(a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mdn = median(time_vals.data(), rounds);
|
uint64_t t0;
|
||||||
// free(time_vals);
|
sched_yield();
|
||||||
return mdn;
|
for (size_t i = 0; i < rounds; i++) {
|
||||||
|
mfence();
|
||||||
|
t0 = rdtscp();
|
||||||
|
*a1;
|
||||||
|
*a2;
|
||||||
|
time_vals[i] = rdtscp() - t0;
|
||||||
|
lfence();
|
||||||
|
clflush(a1);
|
||||||
|
clflush(a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mdn = median(time_vals.data(), rounds);
|
||||||
|
// free(time_vals);
|
||||||
|
return mdn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pop_options
|
#pragma pop_options
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
char *get_rnd_addr(char *base, size_t m_size, size_t align) {
|
char *
|
||||||
return (char *)ALIGN_TO((uint64_t)base, (uint64_t)align) +
|
get_rnd_addr(char *base, size_t m_size, size_t align)
|
||||||
ALIGN_TO(rand() % m_size, (uint64_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)
|
||||||
//----------------------------------------------------------
|
{
|
||||||
uint64_t get_phys_addr(uint64_t v_addr) {
|
return ((entry) & 0x3fffffffffffff);
|
||||||
uint64_t entry;
|
|
||||||
uint64_t offset = (v_addr / 4096) * sizeof(entry);
|
|
||||||
uint64_t pfn;
|
|
||||||
int fd = open("/proc/self/pagemap", O_RDONLY);
|
|
||||||
assert(fd >= 0);
|
|
||||||
int bytes_read = pread(fd, &entry, sizeof(entry), offset);
|
|
||||||
close(fd);
|
|
||||||
assert(bytes_read == 8);
|
|
||||||
assert(entry & (1ULL << 63));
|
|
||||||
pfn = get_pfn(entry);
|
|
||||||
assert(pfn != 0 && "pfn is zero !!!!!");
|
|
||||||
return (pfn * 4096) | (v_addr & 4095);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
addr_tuple gen_addr_tuple(char *v_addr) {
|
uint64_t
|
||||||
return (addr_tuple){v_addr, get_phys_addr((uint64_t)v_addr)};
|
get_phys_addr(uint64_t v_addr)
|
||||||
|
{
|
||||||
|
uint64_t entry;
|
||||||
|
uint64_t offset = (v_addr / 4096) * sizeof(entry);
|
||||||
|
uint64_t pfn;
|
||||||
|
int fd = open("/proc/self/pagemap", O_RDONLY);
|
||||||
|
assert(fd >= 0);
|
||||||
|
int bytes_read = pread(fd, &entry, sizeof(entry), offset);
|
||||||
|
close(fd);
|
||||||
|
assert(bytes_read == 8);
|
||||||
|
assert(entry & (1ULL << 63));
|
||||||
|
pfn = get_pfn(entry);
|
||||||
|
assert(pfn != 0 && "pfn is zero !!!!!");
|
||||||
|
return (pfn * 4096) | (v_addr & 4095);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------
|
||||||
|
addr_tuple
|
||||||
|
gen_addr_tuple(char *v_addr)
|
||||||
|
{
|
||||||
|
return (addr_tuple){v_addr, get_phys_addr((uint64_t) v_addr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// https://www.cs.umd.edu/~gasarch/TOPICS/factoring/fastgauss.pdf
|
// https://www.cs.umd.edu/~gasarch/TOPICS/factoring/fastgauss.pdf
|
||||||
// gaussian elimination in GF2
|
// 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;
|
size_t height, width, height_t, width_t;
|
||||||
|
|
||||||
height = masks.size();
|
height = masks.size();
|
||||||
width = 0;
|
width = 0;
|
||||||
for (auto m : masks) {
|
for (auto m : masks) {
|
||||||
uint64_t max_one = 64 - __builtin_clzl(m);
|
uint64_t max_one = 64 - __builtin_clzl(m);
|
||||||
width = (max_one > width) ? max_one : width;
|
width = (max_one > width) ? max_one : width;
|
||||||
}
|
|
||||||
|
|
||||||
height_t = width;
|
|
||||||
width_t = height;
|
|
||||||
|
|
||||||
std::vector<std::vector<bool>> mtx(height, std::vector<bool>(width));
|
|
||||||
std::vector<std::vector<bool>> mtx_t(height_t, std::vector<bool>(width_t));
|
|
||||||
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 i = 0; i < height; i++) {
|
height_t = width;
|
||||||
for (size_t j = 0; j < width; j++) {
|
width_t = height;
|
||||||
mtx_t[j][i] = mtx[i][j];
|
|
||||||
|
std::vector<std::vector<bool>> mtx(height, std::vector<bool>(width));
|
||||||
|
std::vector<std::vector<bool>> mtx_t(height_t, std::vector<bool>(width_t));
|
||||||
|
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))); }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int64_t pvt_col = 0;
|
for (size_t i = 0; i < height; i++) {
|
||||||
|
for (size_t j = 0; j < width; j++) { mtx_t[j][i] = mtx[i][j]; }
|
||||||
|
}
|
||||||
|
|
||||||
while (pvt_col < width_t) {
|
int64_t pvt_col = 0;
|
||||||
for (uint64_t row = 0; row < height_t; row++) {
|
|
||||||
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;
|
|
||||||
|
|
||||||
// column sum
|
while (pvt_col < width_t) {
|
||||||
for (size_t r = 0; r < height_t; r++) {
|
for (uint64_t row = 0; row < height_t; row++) {
|
||||||
mtx_t[r][c] = BOOL_XOR(mtx_t[r][c], mtx_t[r][pvt_col]);
|
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;
|
||||||
|
|
||||||
|
// 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]); }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
pvt_col++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pvt_col++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filtered_masks;
|
return filtered_masks;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// from https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
|
// from https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
|
||||||
uint64_t next_bit_permutation(uint64_t v) {
|
uint64_t
|
||||||
uint64_t t = v | (v - 1);
|
next_bit_permutation(uint64_t v)
|
||||||
return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzl(v) + 1));
|
{
|
||||||
|
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,
|
std::vector<uint64_t>
|
||||||
size_t max_fn_bits, size_t msb,
|
find_functions(std::vector<set_t> sets, size_t max_fn_bits, size_t msb, uint64_t flags)
|
||||||
uint64_t flags) {
|
{
|
||||||
|
|
||||||
std::vector<uint64_t> masks;
|
std::vector<uint64_t> masks;
|
||||||
verbose_printerr("~~~~~~~~~~ Candidate functions ~~~~~~~~~~\n");
|
verbose_printerr("~~~~~~~~~~ Candidate functions ~~~~~~~~~~\n");
|
||||||
|
|
||||||
for (size_t bits = 1L; bits <= max_fn_bits; bits++) {
|
for (size_t bits = 1L; bits <= max_fn_bits; bits++) {
|
||||||
uint64_t fn_mask =
|
uint64_t fn_mask = ((1L << (bits)) - 1);// avoid the first 6 bits since they are the cacheline bits
|
||||||
((1L << (bits)) -
|
uint64_t last_mask = (fn_mask << (msb - bits));
|
||||||
1); // avoid the first 6 bits since they are the cacheline bits
|
fn_mask <<= CL_SHIFT;
|
||||||
uint64_t last_mask = (fn_mask << (msb - bits));
|
verbose_printerr("[ LOG ] - #Bits: %ld \n", bits);
|
||||||
fn_mask <<= CL_SHIFT;
|
while (fn_mask != last_mask) {
|
||||||
verbose_printerr("[ LOG ] - #Bits: %ld \n", bits);
|
if (fn_mask & LS_BITMASK(6)) {
|
||||||
while (fn_mask != last_mask) {
|
fn_mask = next_bit_permutation(fn_mask);
|
||||||
if (fn_mask & LS_BITMASK(6)) {
|
continue;
|
||||||
fn_mask = next_bit_permutation(fn_mask);
|
}
|
||||||
continue;
|
for (size_t idx = 0; idx < sets.size(); idx++) {
|
||||||
}
|
set_t curr_set = sets[idx];
|
||||||
for (size_t idx = 0; idx < sets.size(); idx++) {
|
size_t inner_cnt = 0;
|
||||||
set_t curr_set = sets[idx];
|
for (size_t i = 1; i < curr_set.size(); i++) {
|
||||||
size_t inner_cnt = 0;
|
uint64_t res_base = __builtin_parityl(curr_set[0].p_addr & fn_mask);
|
||||||
for (size_t i = 1; i < curr_set.size(); i++) {
|
uint64_t res_probe = __builtin_parityl(curr_set[i].p_addr & fn_mask);
|
||||||
uint64_t res_base = __builtin_parityl(curr_set[0].p_addr & fn_mask);
|
if (res_base != res_probe) { goto next_mask; }
|
||||||
uint64_t res_probe = __builtin_parityl(curr_set[i].p_addr & fn_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));
|
||||||
}
|
masks.push_back(fn_mask);
|
||||||
|
|
||||||
|
next_mask:
|
||||||
|
fn_mask = next_bit_permutation(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:
|
|
||||||
fn_mask = next_bit_permutation(fn_mask);
|
|
||||||
}
|
}
|
||||||
}
|
verbose_printerr("~~~~~~~~~~ Found Functions ~~~~~~~~~~\n");
|
||||||
verbose_printerr("~~~~~~~~~~ Found Functions ~~~~~~~~~~\n");
|
masks = reduce_masks(masks);
|
||||||
masks = reduce_masks(masks);
|
if (flags & F_VERBOSE) {
|
||||||
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) {
|
return masks;
|
||||||
fprintf(stdout, "0x%lx\n", m);
|
|
||||||
}
|
|
||||||
return masks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> find_set_bits(uint64_t val) {
|
std::vector<int>
|
||||||
std::vector<int> set_bits;
|
find_set_bits(uint64_t val)
|
||||||
for (int i = 0; i < 64; i++) {
|
{
|
||||||
if (!(val & (1ULL << i)))
|
std::vector<int> set_bits;
|
||||||
continue;
|
for (int i = 0; i < 64; i++) {
|
||||||
|
if (!(val & (1ULL << i))) continue;
|
||||||
|
|
||||||
set_bits.push_back(i);
|
set_bits.push_back(i);
|
||||||
}
|
}
|
||||||
return set_bits;
|
return set_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
std::vector<uint8_t> get_dram_fn(uint64_t addr,
|
std::vector<uint8_t>
|
||||||
std::vector<uint64_t> fn_masks) {
|
get_dram_fn(uint64_t addr, std::vector<uint64_t> fn_masks)
|
||||||
std::vector<uint8_t> addr_dram;
|
{
|
||||||
for (auto fn : fn_masks) {
|
std::vector<uint8_t> addr_dram;
|
||||||
addr_dram.push_back(__builtin_parityl(addr & fn));
|
for (auto fn : fn_masks) { addr_dram.push_back(__builtin_parityl(addr & fn)); }
|
||||||
}
|
return addr_dram;
|
||||||
return addr_dram;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@ -254,168 +249,155 @@ 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
|
@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
|
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,
|
uint64_t
|
||||||
mem_buff_t mem, uint64_t threshold, uint64_t flags) {
|
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));
|
addr_tuple base_addr = gen_addr_tuple(get_rnd_addr(mem.buffer, mem.size, 0));
|
||||||
std::vector<set_t> same_row_sets;
|
std::vector<set_t> same_row_sets;
|
||||||
|
|
||||||
verbose_printerr("~~~~~~~~~~ Looking for row bits ~~~~~~~~~~\n");
|
verbose_printerr("~~~~~~~~~~ Looking for row bits ~~~~~~~~~~\n");
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
verbose_printerr("[LOG] - Set #%d\n", i);
|
verbose_printerr("[LOG] - Set #%d\n", i);
|
||||||
addr_tuple base_addr = sets[i][0];
|
addr_tuple base_addr = sets[i][0];
|
||||||
std::vector<uint8_t> base_dram =
|
std::vector<uint8_t> base_dram = get_dram_fn((uint64_t) base_addr.p_addr, fn_masks);
|
||||||
get_dram_fn((uint64_t)base_addr.p_addr, fn_masks);
|
same_row_sets.push_back({base_addr});
|
||||||
same_row_sets.push_back({base_addr});
|
uint64_t cnt = 0;
|
||||||
uint64_t cnt = 0;
|
while (cnt < ROW_SET_CNT) {
|
||||||
while (cnt < ROW_SET_CNT) {
|
|
||||||
|
|
||||||
addr_tuple tmp = gen_addr_tuple(get_rnd_addr(mem.buffer, mem.size, 0));
|
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)
|
if (get_dram_fn((uint64_t) tmp.p_addr, fn_masks) != base_dram) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
uint64_t time = time_tuple((volatile char *)base_addr.v_addr,
|
uint64_t time = time_tuple((volatile char *) base_addr.v_addr, (volatile char *) tmp.v_addr, 1000);
|
||||||
(volatile char *)tmp.v_addr, 1000);
|
|
||||||
|
|
||||||
if (time > threshold)
|
if (time > threshold) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
verbose_printerr("[LOG] - %lx - %lx\t Time: %ld <== GOTCHA\n",
|
verbose_printerr("[LOG] - %lx - %lx\t Time: %ld <== GOTCHA\n", base_addr.p_addr, tmp.p_addr, time);
|
||||||
base_addr.p_addr, tmp.p_addr, time);
|
|
||||||
|
|
||||||
same_row_sets[i].push_back(tmp);
|
same_row_sets[i].push_back(tmp);
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
while (row_mask < last_mask) {
|
|
||||||
if (row_mask & LS_BITMASK(CL_SHIFT)) {
|
|
||||||
row_mask = next_bit_permutation(row_mask);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto addr_pool : same_row_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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
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
|
||||||
|
|
||||||
next_mask:
|
while (row_mask < last_mask) {
|
||||||
row_mask = next_bit_permutation(row_mask);
|
if (row_mask & LS_BITMASK(CL_SHIFT)) {
|
||||||
}
|
row_mask = next_bit_permutation(row_mask);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// super hackish way to recover the real row mask
|
for (auto addr_pool : same_row_sets) {
|
||||||
for (auto m : fn_masks) {
|
addr_tuple base_addr = addr_pool[0];
|
||||||
uint64_t lsb = (1 << (__builtin_ctzl(m) + 1));
|
for (int i = 1; i < addr_pool.size(); i++) {
|
||||||
if (lsb & row_mask) {
|
addr_tuple tmp = addr_pool[i];
|
||||||
row_mask ^= (1 << __builtin_ctzl(m));
|
if ((tmp.p_addr & row_mask) != (base_addr.p_addr & row_mask)) { goto next_mask; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
next_mask:
|
||||||
|
row_mask = next_bit_permutation(row_mask);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
verbose_printerr("[LOG] - Row mask: 0x%0lx \t\t bits: %s\n", row_mask,
|
// super hackish way to recover the real row mask
|
||||||
bit_string(row_mask));
|
for (auto m : fn_masks) {
|
||||||
printf("0x%lx\n", row_mask);
|
uint64_t lsb = (1 << (__builtin_ctzl(m) + 1));
|
||||||
return row_mask;
|
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));
|
||||||
|
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,
|
void
|
||||||
char *o_file, uint64_t flags) {
|
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;
|
time_t t;
|
||||||
|
|
||||||
int o_fd = 0;
|
int o_fd = 0;
|
||||||
int huge_fd = 0;
|
int huge_fd = 0;
|
||||||
std::vector<set_t> sets;
|
std::vector<set_t> sets;
|
||||||
// std::vector<char*> used_addr;
|
// std::vector<char*> used_addr;
|
||||||
std::set<char *> used_addr;
|
std::set<char *> used_addr;
|
||||||
std::vector<uint64_t> fn_masks;
|
std::vector<uint64_t> fn_masks;
|
||||||
|
|
||||||
srand((unsigned)time(&t));
|
srand((unsigned) time(&t));
|
||||||
|
|
||||||
if (flags & F_EXPORT) {
|
if (flags & F_EXPORT) {
|
||||||
if (o_file == NULL) {
|
if (o_file == NULL) {
|
||||||
fprintf(stderr, "[ERROR] - Missing export file name\n");
|
fprintf(stderr, "[ERROR] - Missing export file name\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((o_fd = open(o_file, O_CREAT | O_RDWR, 0644)) == -1) {
|
||||||
|
perror("[ERROR] - Unable to create export file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
dprintf(o_fd, O_HEADER);
|
||||||
}
|
}
|
||||||
if ((o_fd = open(o_file, O_CREAT | O_RDWR, 0644)) == -1) {
|
|
||||||
perror("[ERROR] - Unable to create export file");
|
mem_buff_t mem = {
|
||||||
exit(1);
|
.buffer = NULL,
|
||||||
|
.size = m_size,
|
||||||
|
.flags = flags,
|
||||||
|
};
|
||||||
|
|
||||||
|
alloc_buffer(&mem);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// used_addr.push_back(rnd_addr);
|
||||||
|
used_addr.insert(rnd_addr);
|
||||||
|
|
||||||
|
addr_tuple tp = gen_addr_tuple(rnd_addr);
|
||||||
|
bool found_set = false;
|
||||||
|
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); }
|
||||||
|
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);
|
||||||
|
sets[idx].push_back(tp);
|
||||||
|
found_set = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found_set) {
|
||||||
|
sets.push_back({tp});
|
||||||
|
verbose_printerr("[LOG] - Set: %03ld -\t %p "
|
||||||
|
" <== NEW!!\n",
|
||||||
|
sets.size(), tp.v_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dprintf(o_fd, O_HEADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_buff_t mem = {
|
filter_sets(sets, SET_SIZE);
|
||||||
.buffer = NULL,
|
|
||||||
.size = m_size,
|
|
||||||
.flags = flags,
|
|
||||||
};
|
|
||||||
|
|
||||||
alloc_buffer(&mem);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// used_addr.push_back(rnd_addr);
|
|
||||||
used_addr.insert(rnd_addr);
|
|
||||||
|
|
||||||
addr_tuple tp = gen_addr_tuple(rnd_addr);
|
|
||||||
bool found_set = false;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
sets[idx].push_back(tp);
|
|
||||||
found_set = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found_set) {
|
|
||||||
sets.push_back({tp});
|
|
||||||
verbose_printerr("[LOG] - Set: %03ld -\t %p "
|
|
||||||
" <== NEW!!\n",
|
|
||||||
sets.size(), tp.v_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filter_sets(sets, SET_SIZE);
|
|
||||||
|
|
||||||
#ifdef DEBUG_SETS
|
#ifdef DEBUG_SETS
|
||||||
fprintf(stderr,
|
fprintf(stderr, "[ LOG ] - Cleansing sets. This may take a while... stay put\n");
|
||||||
"[ LOG ] - Cleansing sets. This may take a while... stay put\n");
|
verify_sets(sets, threshold, rounds);
|
||||||
verify_sets(sets, threshold, rounds);
|
fprintf(stderr, "[ LOG ] - Done\n");
|
||||||
fprintf(stderr, "[ LOG ] - Done\n");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (flags & F_VERBOSE) {
|
if (flags & F_VERBOSE) { print_sets(sets); }
|
||||||
print_sets(sets);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn_masks = find_functions(sets, 6, 30, flags);
|
fn_masks = find_functions(sets, 6, 30, flags);
|
||||||
uint64_t row_mask = find_row_mask(sets, fn_masks, mem, threshold, flags);
|
uint64_t row_mask = find_row_mask(sets, fn_masks, mem, threshold, flags);
|
||||||
|
|
||||||
free_buffer(&mem);
|
free_buffer(&mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fin.
|
// Fin.
|
||||||
@ -423,87 +405,86 @@ void rev_mc(size_t sets_cnt, size_t threshold, size_t rounds, size_t m_size,
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
bool is_in(char *val, std::set<char *> arr) {
|
bool
|
||||||
return arr.find(val) != arr.end();
|
is_in(char *val, std::set<char *> arr)
|
||||||
|
{
|
||||||
|
return arr.find(val) != arr.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_in(char *val, std::vector<char *> arr) {
|
bool
|
||||||
for (auto v : arr) {
|
is_in(char *val, std::vector<char *> arr)
|
||||||
if (val == v) {
|
{
|
||||||
return true;
|
for (auto v : arr) {
|
||||||
|
if (val == v) { return true; }
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
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;
|
size_t found_sets = 0;
|
||||||
|
|
||||||
for (int i = 0; i < sets.size(); i++) {
|
for (int i = 0; i < sets.size(); i++) {
|
||||||
set_t curr_set = sets[i];
|
set_t curr_set = sets[i];
|
||||||
if (curr_set.size() > set_size) {
|
if (curr_set.size() > set_size) { found_sets += 1; }
|
||||||
found_sets += 1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (found_sets > set_cnt) {
|
if (found_sets > set_cnt) {
|
||||||
fprintf(
|
fprintf(stderr, "[ERROR] - Found too many sets. Is %ld the correct number of sets?\n", set_cnt);
|
||||||
stderr,
|
exit(1);
|
||||||
"[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;
|
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(); s++) {
|
for (auto s = sets.begin(); s < sets.end(); s++) {
|
||||||
if (s->size() < set_size) {
|
if (s->size() < set_size) {
|
||||||
sets.erase(s);
|
sets.erase(s);
|
||||||
s -= 1;
|
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++) {
|
for (int idx = 0; idx < sets.size(); idx++) {
|
||||||
fprintf(stderr, "[LOG] - Set: %d\tSize: %ld\n", idx, sets[idx].size());
|
fprintf(stderr, "[LOG] - Set: %d\tSize: %ld\n", idx, sets[idx].size());
|
||||||
for (auto tmp : sets[idx]) {
|
for (auto tmp : sets[idx]) { fprintf(stderr, "\tv_addr:%p - p_addr:%p\n", tmp.v_addr, (void *) tmp.p_addr); }
|
||||||
fprintf(stderr, "\tv_addr:%p - p_addr:%p\n", tmp.v_addr,
|
|
||||||
(void *)tmp.p_addr);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_SETS
|
#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) {
|
for (auto s : sets) {
|
||||||
// test every address against all the addresses in the set
|
// test every address against all the addresses in the set
|
||||||
for (auto tp_base = s.begin(); tp_base < s.end(); tp_base++) {
|
for (auto tp_base = s.begin(); tp_base < s.end(); tp_base++) {
|
||||||
uint64_t conflicts = 0;
|
uint64_t conflicts = 0;
|
||||||
for (auto tp_probe = s.begin(); tp_probe < s.end(); tp_probe++) {
|
for (auto tp_probe = s.begin(); tp_probe < s.end(); tp_probe++) {
|
||||||
if (tp_base == tp_probe)
|
if (tp_base == tp_probe) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
uint64_t time = time_tuple((volatile char *)tp_base->v_addr,
|
uint64_t time =
|
||||||
(volatile char *)tp_probe->v_addr, rounds);
|
time_tuple((volatile char *) tp_base->v_addr, (volatile char *) tp_probe->v_addr, rounds);
|
||||||
if (time > threshold) {
|
if (time > threshold) { conflicts += 1; }
|
||||||
conflicts += 1;
|
}
|
||||||
|
if (!(conflicts > VALID_THRESH * s.size())) {
|
||||||
|
fprintf(stderr, "[ LOG ] - Removing: %p\n", tp_base->v_addr);
|
||||||
|
s.erase(tp_base--);// reset the iterator
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!(conflicts > VALID_THRESH * s.size())) {
|
|
||||||
fprintf(stderr, "[ LOG ] - Removing: %p\n", tp_base->v_addr);
|
|
||||||
s.erase(tp_base--); // reset the iterator
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,87 +1,84 @@
|
|||||||
#include <sys/types.h>
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <errno.h>
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
// Memory alloc
|
// Memory alloc
|
||||||
|
|
||||||
int alloc_buffer(mem_buff_t* mem) {
|
int
|
||||||
if (mem->buffer != NULL) {
|
alloc_buffer(mem_buff_t *mem)
|
||||||
fprintf(stderr, "[ERROR] - Memory already allocated\n");
|
{
|
||||||
}
|
if (mem->buffer != NULL) { fprintf(stderr, "[ERROR] - Memory already allocated\n"); }
|
||||||
|
|
||||||
uint64_t alloc_flags = MAP_PRIVATE | MAP_POPULATE | MAP_ANONYMOUS;
|
uint64_t alloc_flags = MAP_PRIVATE | MAP_POPULATE | MAP_ANONYMOUS;
|
||||||
|
|
||||||
mem->buffer = (char*) mmap(NULL, mem->size, PROT_READ | PROT_WRITE, alloc_flags, -1, 0);
|
mem->buffer = (char *) mmap(NULL, mem->size, PROT_READ | PROT_WRITE, alloc_flags, -1, 0);
|
||||||
if (mem->buffer == MAP_FAILED) {
|
if (mem->buffer == MAP_FAILED) {
|
||||||
perror("[ERROR] - mmap() failed");
|
perror("[ERROR] - mmap() failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem->flags & F_VERBOSE) {
|
|
||||||
fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
||||||
fprintf(stderr, "[ MEM ] - Buffer: %p\n", mem->buffer);
|
|
||||||
fprintf(stderr, "[ MEM ] - Size: %ld\n", mem->size);
|
|
||||||
fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
if (mem->flags & F_VERBOSE) {
|
||||||
|
fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||||
|
fprintf(stderr, "[ MEM ] - Buffer: %p\n", mem->buffer);
|
||||||
|
fprintf(stderr, "[ MEM ] - Size: %ld\n", mem->size);
|
||||||
|
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);
|
return munmap(mem->buffer, mem->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
double mean(uint64_t* vals, size_t size) {
|
double
|
||||||
uint64_t avg = 0;
|
mean(uint64_t *vals, size_t size)
|
||||||
for (size_t i = 0; i < size; i++) {
|
{
|
||||||
avg += vals[i];
|
uint64_t avg = 0;
|
||||||
}
|
for (size_t i = 0; i < size; i++) { avg += vals[i]; }
|
||||||
return ((double)avg) / size;
|
return ((double) avg) / size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gt(const void * a, const void * b) {
|
int
|
||||||
return ( *(int*)a - *(int*)b );
|
gt(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return (*(int *) a - *(int *) b);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t median(uint64_t* vals, size_t size) {
|
uint64_t
|
||||||
qsort(vals, size, sizeof(uint64_t), gt);
|
median(uint64_t *vals, size_t size)
|
||||||
return ((size%2)==0) ? vals[size/2] : (vals[(size_t)size/2]+vals[((size_t)size/2+1)])/2;
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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, "+ "); }
|
||||||
|
sprintf(itoa_str, "%d ", shift);
|
||||||
|
strcat(bit_str, itoa_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char* bit_string(uint64_t val) {
|
return bit_str;
|
||||||
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, "+ ");
|
|
||||||
}
|
|
||||||
sprintf(itoa_str, "%d ", shift);
|
|
||||||
strcat(bit_str, itoa_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bit_str;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user