mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
6322f794d1
* This branch contains support for new architectures. * Initial start to support for AArch 32 * Progress * Forgot the new files * Added all data Integer processing instructions without S + ADDS and started ANDS * Updated * Finished Integer Data Processing with three registers, added integer data processing with 2 regs + immediate, started MUL instructions * UMULL, UMULLS, UMLAL, UMLALS * Corrected condition for addend or 0 immediate for UMULL/UMLAL + SMULL/SMLAL instructions * Correct ops in Binary.cpp * UMAAL * SMULL, SMULLS, SMLAL, SMLALS + corrected acc was missing shift left in concatination * Updated decoding instructions based on top level encodings * Update returns around kDataProcessingRI and kDataProcessingI with comments to explain the correlation to the instruction rep * Added appropriate inst.category flags to Multiply and accumulate * Load/Store Word, Unsigned Byte (immediate, literal) && start of Logical Arithmetic (three register, immediate shift) * Was missing UMAAL DEF_ISEL in Binary.cpp * AddAddrRegOp * Logical Arithmetic (three register, immediate shift) without accounting for the possible PC jump * Made DecodeA32ExpandImm much much smaller * Replaced some imm ops with AddImmOp calls * Created AddShiftOp * Added interpreter for evaluating new PC value at decoding time to handle direct jumps and conditional jumps * Created EvalPCDest added PC evaluation to Logical Arithmetic Instructions * AddShiftOp -> AddShiftOp, AddShiftThenExtractOp, AddExtractThenShiftOp * Cleaned up some formatting, Renamed DecodeA32ExpandImm to ExpandTo32AddImmAddCarry and added a clarifying comment * Added comment to EvalPCDest for clarity * Cleaned up some things, updated the decoding semantics and semantics for the logical instructions * Shortened kLogArithEvaluators and fixed a bug * Updates from testing instructions * Fixed DEF_ISEL for pre/post index instructions in MEM.cpp * Integer Test and Compare (two register, immediate shift) * Logical Arithmetic (two register and immediate) * Integer Test and Compare (one register and immediate) * Added to the top level encoding infrastructure to handle the Data-processing register (register shift) set of instructions and 3 corresponding subsets * Add structs for the 3 subsets of Data-processing register (register shift) * Code status before refactoring operand types * This branch contains support for new architectures. * Initial start to support for AArch 32 * Progress * Forgot the new files * Added all data Integer processing instructions without S + ADDS and started ANDS * Updated * Finished Integer Data Processing with three registers, added integer data processing with 2 regs + immediate, started MUL instructions * UMULL, UMULLS, UMLAL, UMLALS * Corrected condition for addend or 0 immediate for UMULL/UMLAL + SMULL/SMLAL instructions * Correct ops in Binary.cpp * UMAAL * SMULL, SMULLS, SMLAL, SMLALS + corrected acc was missing shift left in concatination * Updated decoding instructions based on top level encodings * Update returns around kDataProcessingRI and kDataProcessingI with comments to explain the correlation to the instruction rep * Added appropriate inst.category flags to Multiply and accumulate * Load/Store Word, Unsigned Byte (immediate, literal) && start of Logical Arithmetic (three register, immediate shift) * Was missing UMAAL DEF_ISEL in Binary.cpp * AddAddrRegOp * Logical Arithmetic (three register, immediate shift) without accounting for the possible PC jump * Made DecodeA32ExpandImm much much smaller * Replaced some imm ops with AddImmOp calls * Created AddShiftOp * Added interpreter for evaluating new PC value at decoding time to handle direct jumps and conditional jumps * Created EvalPCDest added PC evaluation to Logical Arithmetic Instructions * AddShiftOp -> AddShiftOp, AddShiftThenExtractOp, AddExtractThenShiftOp * Cleaned up some formatting, Renamed DecodeA32ExpandImm to ExpandTo32AddImmAddCarry and added a clarifying comment * Added comment to EvalPCDest for clarity * Cleaned up some things, updated the decoding semantics and semantics for the logical instructions * Shortened kLogArithEvaluators and fixed a bug * Updates from testing instructions * Fixed DEF_ISEL for pre/post index instructions in MEM.cpp * Integer Test and Compare (two register, immediate shift) * Logical Arithmetic (two register and immediate) * Integer Test and Compare (one register and immediate) * Added to the top level encoding infrastructure to handle the Data-processing register (register shift) set of instructions and 3 corresponding subsets * Add structs for the 3 subsets of Data-processing register (register shift) * Code status before refactoring operand types * Finished updates off master * Start of operand refactor * Finished Expression Operand Support * Fix the .gitignore to add AArch32 to lib/Arch && removed all extra rrx ops from semantics * Updated .gitignore again, Added AddShiftRegRegOperand, Updated AddShiftRegImmOperand, Finished Register shift instructions for Integer Test and Compare, Logical Arithmetic, Integer Data Processing * Updated ROR in AddShiftRegRegOperand * Created ExtractAndZExtExpr * Fixed comment formatting in if else statements * Created RORExpr * Small fixes * Small fix in Logical Arithmetic (two register and immediate) * Corrected AddShiftRegRegOperand and cleaned it up. Split the carry op into a separate function. * conditional support + Start of Branch instructions * Created AddExprOp, cleaned up some expressions in reg shifted reg, and updated some occurances of ShiftThenExtractOp with ExtractAndZExtExpr * Updates from testing register shifted by register value inst * Fix to ROR in AddShiftRegCarryOperand * Corrected negation in DecodeCondition * DecodeCondition edit * DecodeCondition and AddShiftRegCarryOperand edits * Updated arch_for_decode to arch * Halfword Multiply and Accumulate * Edits from testing Halfword Multiply and Accumulate * Changed order of operands in Halfword Multiply and Accumulate to better reflect inst format + updated inst errors * Branch (Imm) & BX/BXL * Update aarch32 cmake * cmake update * CLZ * Forgot BITBYTE.cpp * MOVT * Integer Saturating Arithmetic * updated semantics in SMLAWh & SMLAh to use Select for setting PSTATE.Q * Started Load/Store Word, Unsigned Byte (register) & fixed MOV halfword * Load/Store Word, Unsigned Byte (register) * Finished testing load/Store Word, Unsigned Byte (register) * Load/Store Dual, Half, Signed Byte (register) * Rest of Extra load store: Load/Store Dual, Half, Signed Byte (immediate, literal) * Finished testing all the Load/store additions * Signed multiply, Divide * Cleaned up SExt some * Saturate Insts and Start of Load Store Multiple - STMDB and LDM (aliases which support PUSH and POP of multiple regs) * Condensed args in STMDB and LDM semantics * Rest of Multiple Load/Store that do not execute in a different mode * Bitfield Extract * Extend and Add * fix * NOP * Small fix * Simplified the bit reps in TryMoveSpecialRegisterAndHintsI * Moved Bitfield extract semantics out of BINARY and into BITBYTE * Finished correcting S/ZExt and Trunc use * Ran scripts/format-files to format * Smoke Test * Add false delay slot to kCategoryConditionalDirectFunctionCall * CI: Use single packaging job, add changelog support (#491) * CI: Add tag handler (#492) * Delay slot fixes to TraceLifter Co-authored-by: Peter Goodman <peter.goodman@gmail.com> Co-authored-by: Alessandro Gario <5714290+alessandrogario@users.noreply.github.com>
153 lines
4.2 KiB
C++
153 lines
4.2 KiB
C++
/*
|
|
* Copyright (c) 2018 Trail of Bits, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <gflags/gflags.h>
|
|
#include <glog/logging.h>
|
|
#include <llvm/IR/Function.h>
|
|
#include <llvm/IR/GlobalValue.h>
|
|
#include <llvm/IR/Instructions.h>
|
|
#include <llvm/IR/LLVMContext.h>
|
|
#include <llvm/IR/Module.h>
|
|
#include <llvm/IR/Type.h>
|
|
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <fstream>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
#include "remill/Arch/Arch.h"
|
|
#include "remill/Arch/Instruction.h"
|
|
#include "remill/Arch/Name.h"
|
|
#include "remill/BC/IntrinsicTable.h"
|
|
#include "remill/BC/Lifter.h"
|
|
#include "remill/BC/Util.h"
|
|
#include "remill/OS/OS.h"
|
|
#include "tests/X86/Test.h"
|
|
|
|
#ifdef __APPLE__
|
|
# define SYMBOL_PREFIX "_"
|
|
#else
|
|
# define SYMBOL_PREFIX ""
|
|
#endif
|
|
|
|
DEFINE_string(bc_out, "",
|
|
"Name of the file in which to place the generated bitcode.");
|
|
|
|
DECLARE_string(arch);
|
|
DECLARE_string(os);
|
|
|
|
namespace {
|
|
|
|
class TestTraceManager : public remill::TraceManager {
|
|
public:
|
|
virtual ~TestTraceManager(void) = default;
|
|
|
|
void SetLiftedTraceDefinition(uint64_t addr,
|
|
llvm::Function *lifted_func) override {
|
|
traces[addr] = lifted_func;
|
|
}
|
|
|
|
llvm::Function *GetLiftedTraceDeclaration(uint64_t addr) override {
|
|
auto trace_it = traces.find(addr);
|
|
if (trace_it != traces.end()) {
|
|
return trace_it->second;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
llvm::Function *GetLiftedTraceDefinition(uint64_t addr) override {
|
|
return GetLiftedTraceDeclaration(addr);
|
|
}
|
|
|
|
bool TryReadExecutableByte(uint64_t addr, uint8_t *byte) override {
|
|
auto byte_it = memory.find(addr);
|
|
if (byte_it != memory.end()) {
|
|
*byte = byte_it->second;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public:
|
|
std::unordered_map<uint64_t, uint8_t> memory;
|
|
std::unordered_map<uint64_t, llvm::Function *> traces;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
extern "C" int main(int argc, char *argv[]) {
|
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
|
google::InitGoogleLogging(argv[0]);
|
|
|
|
DLOG(INFO) << "Generating tests.";
|
|
|
|
std::vector<const test::TestInfo *> tests;
|
|
for (auto i = 0U;; ++i) {
|
|
const auto &test = test::__x86_test_table_begin[i];
|
|
if (&test >= &(test::__x86_test_table_end[0])) {
|
|
break;
|
|
}
|
|
tests.push_back(&test);
|
|
}
|
|
|
|
TestTraceManager manager;
|
|
|
|
// Add all code byts from the test cases to the memory.
|
|
for (auto test : tests) {
|
|
for (auto addr = test->test_begin; addr < test->test_end; ++addr) {
|
|
manager.memory[addr] = *reinterpret_cast<uint8_t *>(addr);
|
|
}
|
|
}
|
|
|
|
llvm::LLVMContext context;
|
|
auto os_name = remill::GetOSName(REMILL_OS);
|
|
auto arch_name = remill::GetArchName(FLAGS_arch);
|
|
auto arch = remill::Arch::Build(&context, os_name, arch_name);
|
|
auto module = remill::LoadArchSemantics(arch);
|
|
|
|
remill::IntrinsicTable intrinsics(module.get());
|
|
remill::InstructionLifter inst_lifter(arch, intrinsics);
|
|
remill::TraceLifter trace_lifter(inst_lifter, manager);
|
|
|
|
for (auto test : tests) {
|
|
if (!trace_lifter.Lift(test->test_begin)) {
|
|
LOG(ERROR) << "Unable to lift test " << test->test_name;
|
|
continue;
|
|
}
|
|
|
|
// Make sure the trace for the test has the right name.
|
|
std::stringstream ss;
|
|
ss << SYMBOL_PREFIX << test->test_name << "_lifted";
|
|
|
|
auto lifted_trace = manager.GetLiftedTraceDefinition(test->test_begin);
|
|
lifted_trace->setName(ss.str());
|
|
}
|
|
|
|
DLOG(INFO) << "Serializing bitcode to " << FLAGS_bc_out;
|
|
auto host_arch =
|
|
remill::Arch::Build(&context, os_name, remill::GetArchName(REMILL_ARCH));
|
|
host_arch->PrepareModule(module.get());
|
|
remill::StoreModuleToFile(module.get(), FLAGS_bc_out);
|
|
|
|
DLOG(INFO) << "Done.";
|
|
return 0;
|
|
}
|