400,548 err.txt

Large diffs are not rendered by default.

@@ -1 +1 @@
4346369424
4399437200
@@ -77,11 +77,7 @@ struct CopyMFInitializer : MachineFunctionInitializer {
: TheMF(&MF), Reuse(ReuseFunction) {}

bool initializeMachineFunction(MachineFunction &MF) {
if (Reuse) {
copyFunction(MF);
} else {
moveFunction(MF);
}
copyFunction(MF);

return false;
}
@@ -162,7 +158,7 @@ bool emitDumpRegistersModule(TargetMachine *TM,
auto *MBB = MF.CreateMachineBasicBlock();
MF.push_back(MBB);
auto *Instrumenter = getInstrumenter(TM);
Instrumenter->dumpRegisters(*M, *MBB, Regs);
Instrumenter->dumpRegisters(*M, *MBB, Regs, "_ug_target_reg_data");
Instrumenter->instrumentToReturnNormally(MF, *MBB);
return compileToObjectFile(*M, MF, OutFilename, TM);
}
BIN +26.4 MB (210%) mf_compiler_test
Binary file not shown.
@@ -48,7 +48,7 @@ unsigned Instrumenter::align(unsigned Addr, unsigned Alignment) {
return Aligned;
}

void Instrumenter::calculateRegBufferLayout(Module &M, const std::vector<unsigned> &Regs) {
void Instrumenter::calculateRegBufferLayout(Module &M, const std::vector<unsigned> &Regs, const std::string &BufferName) {
auto &Ctx = M.getContext();

RegInfo.resize(Regs.size());
@@ -76,7 +76,7 @@ void Instrumenter::calculateRegBufferLayout(Module &M, const std::vector<unsigne
auto *RegDataTy = ArrayType::get(Int8Ty, CurOffset);
RegData[&M] =
new GlobalVariable(M, RegDataTy, false, GlobalVariable::ExternalLinkage,
ConstantAggregateZero::get(RegDataTy), "_ug_reg_data");
ConstantAggregateZero::get(RegDataTy), BufferName);

auto *RegInfoArrTy = ArrayType::get(RegInfoTy, Regs.size());
// declare `reg_info`
@@ -93,12 +93,14 @@ void Instrumenter::calculateRegBufferLayout(Module &M, const std::vector<unsigne
// * declare `reg_info(struct{ size_t offset, size}[])` in `M`
// * declare `num_regs`
// * emit code to dump `Regs` at the end of `MBB`
void Instrumenter::dumpRegisters(llvm::Module &M, llvm::MachineBasicBlock &MBB,
const std::vector<unsigned> &Regs) {
void Instrumenter::dumpRegisters(llvm::Module &M,
llvm::MachineBasicBlock &MBB,
const std::vector<unsigned> &Regs,
const std::string &BufferName) {
assert(FreeReg && "FreeReg uninitialized");

if (RegData.find(&M) == RegData.end()) {
calculateRegBufferLayout(M, Regs);
calculateRegBufferLayout(M, Regs, BufferName);
}

auto *MF = MBB.getParent();
@@ -33,7 +33,7 @@ class Instrumenter {
initRegisters();
}

void calculateRegBufferLayout(llvm::Module &M, const std::vector<unsigned> &Regs);
void calculateRegBufferLayout(llvm::Module &M, const std::vector<unsigned> &Regs, const std::string &BufferName);

unsigned getOpcode(const std::string &Name) const {
for (unsigned i = 0; i < MII->getNumOpcodes(); i++) {
@@ -52,7 +52,8 @@ class Instrumenter {
int64_t JmpbfuAddr) const = 0;

void dumpRegisters(llvm::Module &M, llvm::MachineBasicBlock &MBB,
const std::vector<unsigned> &Regs);
const std::vector<unsigned> &Regs,
const std::string &BufferName);

virtual void
instrumentToReturnNormally(llvm::MachineFunction &MF,
2,438 opcode.x

This file was deleted.

12,688 opcodes.x

Large diffs are not rendered by default.

@@ -136,15 +136,15 @@ struct ReplayClient::ClientImpl {
const auto &W = Workers[0];
auto RetRegs = Instrumenter_->getReturnRegs(FnTy);
Instrumenter_->protectRTFrame(MBB, W.FrameBegin, W.FrameSize);
Instrumenter_->dumpRegisters(*M, MBB, RetRegs, "_ug_rewrite_reg_data");
Instrumenter_->unprotectRTFrame(MBB, W.FrameBegin, W.FrameSize);
Instrumenter_->dumpRegisters(*M, MBB, RetRegs);
Instrumenter_->instrumentToReturn(*Rewrite, JmpbufAddr);
}

std::string compile(Module *M, MachineFunction *Rewrite) {
const std::string RewriteObj = std::tmpnam(nullptr);
errs() << "compiling rewrite\n";
compileToObjectFile(*M, *Rewrite, RewriteObj, TM, false);
compileToObjectFile(*M, *Rewrite, RewriteObj, TM, false, false);
const std::string RewriteLib = std::tmpnam(nullptr);
errs() << "linking rewrite\n";
std::system(("cc -shared "+RewriteObj+" -o "+RewriteLib).c_str());
@@ -60,7 +60,7 @@ double Searcher::rand()
MachineFunction *Searcher::synthesize()
{
unsigned cost = 100;
const unsigned MaxInstrs = 5;
const unsigned MaxInstrs = 10;
do {
double r = rand();

@@ -122,6 +122,7 @@ MachineFunction *Searcher::synthesize()
if (!Accept) {
Transform.Undo();
} else {
Transform.Accept();
cost = newCost;
}

@@ -22,7 +22,7 @@ class Searcher {
const float pi {0.16};
// probability of deletion
const float pu {0.16};
const float beta {1.0};
const float beta {10.0};

unsigned calculateCost(std::vector<response> &);
double rand();
@@ -0,0 +1 @@
1462398274
BIN -3.98 KB (94%) server
Binary file not shown.
@@ -38,7 +38,7 @@
#endif

// target reg_data
extern uint8_t _ug_reg_data[];
extern uint8_t _ug_target_reg_data[];
// target reg_info
extern struct reg_info _ug_reg_info[];
extern size_t _ug_num_regs;
@@ -256,9 +256,9 @@ uint32_t spawn_impl(uint32_t (*orig_func)(void), char *funcname) {
if (!rewrite)
respond(cli_fd, make_error(CANT_LOAD_FUNC));

uint8_t *rewrite_reg_data = dlsym(lib, "_ug_reg_data");
uint8_t *rewrite_reg_data = dlsym(lib, "_ug_rewrite_reg_data");
if (!rewrite_reg_data)
respond(cli_fd, make_error("can't load _ug_reg_data"));
respond(cli_fd, make_error("can't load _ug_rewrite_reg_data"));

int ret;
if ((ret = sigsetjmp(jb, 1)) == 0) {
@@ -272,11 +272,17 @@ uint32_t spawn_impl(uint32_t (*orig_func)(void), char *funcname) {
get_mem_dist(_server_heap_bottom, target_heap, heap_size),
reg_dist = 0;

FILE *debug = fopen("err.txt", "a");

int i;
for (i = 0; i < _ug_num_regs; i++) {
reg_dist += get_reg_dist(_ug_reg_info, rewrite_reg_data, target_reg_data, i, i);
fprintf(debug, "%d, %d\n", rewrite_reg_data[0], target_reg_data[0]);
reg_dist += get_reg_dist(_ug_reg_info, rewrite_reg_data, target_reg_data, i, i);
}

fclose(debug);


respond(cli_fd, make_report(reg_dist, stack_dist, heap_dist, crash_signal));
}

@@ -310,7 +316,7 @@ uint32_t spawn_impl(uint32_t (*orig_func)(void), char *funcname) {

// copy reg buffer to shared memory
if (_ug_num_regs > 0) {
memcpy(target_reg_data, _ug_reg_data, reg_buf_size);
memcpy(target_reg_data, _ug_target_reg_data, reg_buf_size);
}

// let go of the child process
@@ -32,6 +32,27 @@ static unsigned choose(unsigned NumChoice) {
return (unsigned)(rand() % (int)NumChoice);
}


/////// cheat
// check if an opcode is supported
static bool isSupported(const MCInstrInfo *MII, unsigned Opc) {
std::string Name = MII->getName(Opc);
return Name.find("ADD32") == 0 ||
Name.find("ADD64") == 0 ||
Name.find("SUB32") == 0 ||
Name.find("SUB64") == 0 ||
Name.find("DIV32") == 0 ||
Name.find("DIV64") == 0 ||
Name.find("MUL32") == 0 ||
Name.find("MUL64") == 0 ||
Name == "MOV64mr" ||
Name == "MOV64rr" ||
Name == "MOV64rm" ||
Name == "MOV32mr" ||
Name == "MOV32rr" ||
Name == "MOV32rm";
}

const TargetRegisterClass *
Transformation::getRegClass(const MCOperandInfo &Op) {
assert(Op.RegClass >= 0);
@@ -45,23 +66,41 @@ Transformation::getRegClass(const MCOperandInfo &Op) {
return RC;
}

// TODO
// cleanup the memory even if no undo
// cleans up memory
void Transformation::Accept() {
switch(PrevTransformation) {
case NOP:
case INSERT:
case SWAP:
case MOVE:
break;
case MUT_OPCODE:
case MUT_OPERAND:
case REPLACE: {
MF->DeleteMachineInstr(Old);
break;
}
case DELETE: {
MF->DeleteMachineInstr(New);
}
}
}

void Transformation::Undo() {
switch (PrevTransformation) {
case NOP:
break;
case MUT_OPCODE:
case MUT_OPERAND:
case REPLACE: {
auto *MBB = New->getParent();
MBB->insert(InstrIterator(New), Old);
New->eraseFromParent();
auto &MBB = *New->getParent();
replaceInst(MBB, New, Old, true);
break;
}

case INSERT: {
New->eraseFromParent();
New->removeFromParent();
MF->DeleteMachineInstr(New);
break;
}

@@ -97,8 +136,7 @@ Transformation::select(Transformation::InstrIterator Except, bool IncludeEnd) {
auto &MBB = *MF->begin();

assert(NumInstrs >= 1 || MBB.instr_begin() != Except);
auto Begin = MBB.instr_begin(),
End = MBB.instr_end();
auto Begin = MBB.instr_begin();

do {
unsigned Idx = IncludeEnd ?
@@ -129,7 +167,8 @@ void Transformation::doSwap(InstrIterator &A, InstrIterator &B) {

static bool hasUnknown(const MCInstrDesc &Desc) {
for (unsigned i = 0; i < Desc.NumOperands; i++) {
if (Desc.OpInfo[i].OperandType == MCOI::OPERAND_UNKNOWN)
if (Desc.OpInfo[i].OperandType == MCOI::OPERAND_UNKNOWN ||
Desc.OpInfo[i].OperandType == MCOI::OPERAND_MEMORY)
return true;
}

@@ -140,7 +179,8 @@ void Transformation::buildOpcodeClasses() {
for (unsigned i = 0; i < TII->getNumOpcodes(); i++) {
const auto &Opcode = TII->get(i);
if (hasUnknown(Opcode) || Opcode.isPseudo() || Opcode.isBranch() ||
Opcode.isReturn() || Opcode.isCall() || Opcode.isVariadic())
Opcode.isReturn() || Opcode.isCall() || Opcode.isVariadic() ||
!isSupported(TII, i))
continue;

OpcodeClasses.insert(i);
@@ -222,11 +262,23 @@ bool Transformation::MutateOperand() {
PrevTransformation = NOP;
return false;
}

unsigned OpIdx = choose(Desc.NumOperands);
const auto &OpInfo = Desc.OpInfo[OpIdx];
auto &Operand = New->getOperand(OpIdx);
randOperand(Operand, OpInfo);

// two address code
if (Desc.getOperandConstraint(0, MCOI::TIED_TO) &&
New->getOperand(0).isReg() &&
New->getOperand(1).isReg()) {
if (OpIdx == 0) {
New->getOperand(1).setReg(New->getOperand(0).getReg());
} else if (OpIdx == 1) {
New->getOperand(0).setReg(New->getOperand(1).getReg());
}
}

return true;
}

@@ -239,7 +291,6 @@ void Transformation::randOperand(MachineOperand &Operand,
}
Operand.setImm(NewImm);
} else {
// FIXME use TRI's getPointerRegClass when OpInfo.isLookupPtrRegClass
assert(Operand.isReg());
const auto *RC = getRegClass(OpInfo);
unsigned NewReg = RC->getRegister(choose(RC->getNumRegs()));
@@ -255,7 +306,8 @@ unsigned Transformation::chooseNonBranchOpcode() {
Desc = &MII->get(choose(NumOpcodes));

} while (Desc->isBranch() || hasUnknown(*Desc) || Desc->isPseudo() ||
Desc->isReturn() || Desc->isCall() || Desc->isVariadic());
Desc->isReturn() || Desc->isCall() || Desc->isVariadic() ||
!isSupported(MII, Desc->Opcode));

return Desc->getOpcode();
}
@@ -265,6 +317,7 @@ MachineInstr *Transformation::randInstr() {
const auto &Desc = MII->get(Opc);
MachineInstr *New = MF->CreateMachineInstr(Desc, DebugLoc());

errs() << "Creating random instruction: `" << MII->getName(Opc) << " ";
// fill the instruction with operands
for (unsigned i = 0; i < Desc.NumOperands; i++) {
const auto &OpInfo = Desc.OpInfo[i];
@@ -274,16 +327,25 @@ MachineInstr *Transformation::randInstr() {
case MCOI::OPERAND_PCREL:
case MCOI::OPERAND_FIRST_TARGET:
case MCOI::OPERAND_IMMEDIATE: {
errs() << "imm, ";
Op = MachineOperand::CreateImm(0);
break;
}

case MCOI::OPERAND_REGISTER: {
errs() << "register, ";
Op = MachineOperand::CreateReg(1, IsDef);
break;
}

case MCOI::OPERAND_MEMORY: {
errs() << "memory";
errs() << "(";
if (OpInfo.RegClass < 0) {
errs() << "imm), ";
} else {
errs() << "reg), ";
}
Op = OpInfo.RegClass < 0 ? MachineOperand::CreateImm(0)
: MachineOperand::CreateReg(1, IsDef);
break;
@@ -297,6 +359,16 @@ MachineInstr *Transformation::randInstr() {
New->addOperand(*MF, Op);
}

// two address code
if (Desc.getOperandConstraint(0, MCOI::TIED_TO)) {
auto &Dest = New->getOperand(0),
&Src = New->getOperand(1);
if (Dest.isReg() && Src.isReg())
Src.setReg(Dest.getReg());
}

errs() << "`\n";

return New;
}

@@ -75,11 +75,8 @@ class Transformation {
// replace `Old` with `New`
static void replaceInst(llvm::MachineBasicBlock &MBB, InstrIterator Old, InstrIterator New, bool Erase=false) {
MBB.insert(Old, New);
if (Erase) {
Old->eraseFromParent();
} else {
Old->removeFromParent();
}
Old->removeFromParent();
if (Erase) MBB.getParent()->DeleteMachineInstr(Old);
}

llvm::MachineInstr *randInstr();
@@ -104,6 +101,7 @@ class Transformation {
llvm::MachineFunction *getFunction() { return MF; }

void Undo();
void Accept(); // the opposite of Undo

bool MutateOpcode();
bool MutateOperand();
BIN +26.6 MB (210%) ug
Binary file not shown.
8 ug.cpp
@@ -109,6 +109,7 @@ int main(int argc, char **argv) {
auto *TargetTy = TargetFunction->getFunctionType();
const auto RetRegs = Instrumenter->getReturnRegs(TargetTy);

errs() << "!!! " << TM->getTargetTriple().normalize() << "\n";
// 3. create `dump_regs.o`
emitDumpRegistersModule(TM.get(), RetRegs, DumpRegsObj);

@@ -128,7 +129,12 @@ int main(int argc, char **argv) {
auto MBB = MF.CreateMachineBasicBlock();
MF.push_back(MBB);

std::srand(std::time(NULL));
std::ofstream debug("seed.txt");
auto seed = 1462398274;//std::time(NULL);
debug << seed << "\n";
debug.close();

std::srand(seed);
Searcher Synthesizer(TM.get(),
M.get(),
&MF,
Binary file not shown.
@@ -1,10 +1,10 @@
/tmp/tuning-czYRPZ/socket,140734748454912,2192
/tmp/tuning-aBDQFg/socket,140734748454912,2192
/tmp/tuning-mHTznn/socket,140734748454912,2192
/tmp/tuning-v3MBBn/socket,140734748454912,2192
/tmp/tuning-wLc3VN/socket,140734748454912,2192
/tmp/tuning-1cyKkC/socket,140734748454912,2192
/tmp/tuning-CwePtS/socket,140734748454912,2192
/tmp/tuning-aW86uk/socket,140734748454912,2192
/tmp/tuning-iH5fHJ/socket,140734748454912,2192
/tmp/tuning-6KS8Po/socket,140734748454912,2192
/tmp/tuning-82Uxud/socket,140734695383040,2144
/tmp/tuning-TSz0tq/socket,140734695383040,2144
/tmp/tuning-Z4auMO/socket,140734695383040,2144
/tmp/tuning-kRBqQp/socket,140734695383040,2144
/tmp/tuning-VFS4vK/socket,140734695383040,2144
/tmp/tuning-p6GW3D/socket,140734695383040,2144
/tmp/tuning-vIrUBI/socket,140734695383040,2144
/tmp/tuning-C68fPZ/socket,140734695383040,2144
/tmp/tuning-1Z71ov/socket,140734695383040,2144
/tmp/tuning-p2ZeA1/socket,140734695383040,2144