Compare commits
20 commits
Author | SHA1 | Date | |
---|---|---|---|
DataHoarder | 875f6588d9 | ||
DataHoarder | 3868034b6b | ||
DataHoarder | 812d1d632f | ||
DataHoarder | 926b1d6a82 | ||
DataHoarder | 83a1b7d280 | ||
DataHoarder | b019ab7684 | ||
DataHoarder | 6a5d9696e7 | ||
DataHoarder | 6d3760c96e | ||
DataHoarder | 2324a561f3 | ||
DataHoarder | bf7c3cefe5 | ||
DataHoarder | 9b2ad65c3a | ||
DataHoarder | 0caa10273e | ||
DataHoarder | f5ce6a92ce | ||
DataHoarder | aa883d3f87 | ||
DataHoarder | cda150ef51 | ||
DataHoarder | 1ed3d43abe | ||
DataHoarder | c3bcf99d6a | ||
DataHoarder | 1fbb828944 | ||
DataHoarder | 15690f54fd | ||
DataHoarder | 81b89b8d11 |
|
@ -3,6 +3,10 @@ kind: pipeline
|
|||
type: docker
|
||||
name: default
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: ubuntu:20.04
|
||||
|
|
|
@ -47,3 +47,42 @@ void AnalysisState::setRegister(const Instruction::AddressWithOffset &address, u
|
|||
uint32_t AnalysisState::getAddressWithOffset(const Instruction::AddressWithOffset &address) const {
|
||||
return address.address + getAddressOffset(address.offset);
|
||||
}
|
||||
|
||||
uint32_t AnalysisState::getDefaultRegisterValue(uint32_t addr) {
|
||||
if(addr == (uint32_t)KnownRegisters::SOFT_RESET){
|
||||
return 0b0000000001111111110111;
|
||||
}else if(addr == (uint32_t)KnownRegisters::DEVICE_CFG){
|
||||
return 0b01111111110000000;
|
||||
}else if(addr == (uint32_t)KnownRegisters::RESET_CFG){
|
||||
return (0x40 << 8) | 0x10;
|
||||
}else if(addr == (uint32_t)KnownRegisters::VITAL_PRODUCT_DATA){
|
||||
return 0xAE21;
|
||||
}else if(addr == (uint32_t)KnownRegisters::SRAM_ERR_IM_0){
|
||||
return 0xFFFFFFFF;
|
||||
}else if(addr == (uint32_t)KnownRegisters::SRAM_ERR_IM_1){
|
||||
return 0x0000FFFF;
|
||||
}else if(addr == (uint32_t)KnownRegisters::SW_IM){
|
||||
return 0xFFFFFFFF;
|
||||
}else if(addr == (uint32_t)KnownRegisters::CHIP_VERSION){
|
||||
return 0x1;
|
||||
}else if(addr == (uint32_t)KnownRegisters::REI_CTRL){
|
||||
return 0b1;
|
||||
}else if(addr == (uint32_t)KnownRegisters::GPIO_IM){
|
||||
return 0xFFFFFFFF;
|
||||
}else if(addr == (uint32_t)KnownRegisters::PLL_PCIE_CTRL){
|
||||
return (0xA << 18) | (0x19 << 10) | (0x1 << 3) | 0b1;
|
||||
}else if(addr == (uint32_t)KnownRegisters::SBUS_PCIE_CFG){
|
||||
return 0b1;
|
||||
}else if(addr == (uint32_t)KnownRegisters::SBUS_PCIE_IM){
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AnalysisState::setRegister(uint32_t addr, uint32_t value) {
|
||||
if(addr == (uint32_t)KnownRegisters::BSM_ARGS){
|
||||
addKnownJump(value & 0xFFFFFF, current, JumpKind::Interrupt);
|
||||
}
|
||||
memory[addr] = value;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ enum class JumpKind {
|
|||
Speculative,
|
||||
Branch,
|
||||
Loop,
|
||||
Return
|
||||
Return,
|
||||
Interrupt
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32_t, std::vector<std::pair<uint32_t, JumpKind>>> AnalysisJumpTable;
|
||||
|
@ -84,15 +85,14 @@ public:
|
|||
|
||||
void setRegister(const Instruction::AddressWithOffset &address, uint32_t value);
|
||||
|
||||
void setRegister(uint32_t addr, uint32_t value) {
|
||||
memory[addr] = value;
|
||||
}
|
||||
void setRegister(uint32_t addr, uint32_t value);
|
||||
|
||||
uint32_t getRegister(const Instruction::AddressWithOffset &address) const;
|
||||
|
||||
uint32_t getRegister(uint32_t addr) const {
|
||||
return memory.find(addr) == memory.end() ? 0 : memory.at(addr);
|
||||
return memory.find(addr) == memory.end() ? getDefaultRegisterValue(addr) : memory.at(addr);
|
||||
}
|
||||
static uint32_t getDefaultRegisterValue(uint32_t addr);
|
||||
|
||||
uint32_t getAddressWithOffset(const Instruction::AddressWithOffset &address) const;
|
||||
|
||||
|
|
|
@ -232,23 +232,31 @@ void ImageFormat::decodeAnalyzeInstructionsAt(uint32_t offset) {
|
|||
break;
|
||||
}
|
||||
|
||||
state.setRegister((uint32_t)KnownRegisters::BSM_CTRL, (state.getRegister((uint32_t)KnownRegisters::BSM_CTRL) & 0xFF) | ((instruction->getEndAddress()) << 8)); // Set EepromAddr as next address
|
||||
auto possibleBranches = instruction->execute(state);
|
||||
|
||||
if ((instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP ||
|
||||
instruction->getCommand() == Instruction::Instruction::CommandOp::RETURN) &&
|
||||
jumpsUsed.find(instruction->getEndAddress()) == jumpsUsed.end()) {
|
||||
jumpsUsed[instruction->getEndAddress()] = false; //TODO: remove this or make it opt-in by default
|
||||
}
|
||||
|
||||
if (jumpsUsed.find(state.current) != jumpsUsed.end() && !jumpsUsed[state.current]) {
|
||||
jumpsUsed.erase(state.current); //Clear to recognize a non-speculative jump
|
||||
}
|
||||
|
||||
if ((instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP ||
|
||||
instruction->getCommand() == Instruction::Instruction::CommandOp::RETURN) &&
|
||||
jumpsUsed.find(instruction->getEndAddress()) == jumpsUsed.end()) {
|
||||
jumpsUsed[instruction->getEndAddress()] = false;
|
||||
}
|
||||
|
||||
if (state.current == 0) {
|
||||
//std::cout << "EXIT DUE TO END " << std::hex << state.previous << " -> " << std::hex << state.current << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//Handle interrupts
|
||||
uint32_t addr = state.getRegister((uint32_t) KnownRegisters::BSM_ARGS) & 0xFFFFFF;
|
||||
if(addr != 0 && jumpsUsed.find(addr) == jumpsUsed.end()){
|
||||
jumpsUsed[addr] = false;
|
||||
}
|
||||
|
||||
if (instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP) {
|
||||
uint32_t nextAddress = instruction->getAddress() - 1;
|
||||
while (true) {
|
||||
|
@ -258,9 +266,9 @@ void ImageFormat::decodeAnalyzeInstructionsAt(uint32_t offset) {
|
|||
const auto &writeInstruction = reinterpret_cast<const std::unique_ptr<Instruction::Write> &>(previousInstruction);
|
||||
if (
|
||||
(
|
||||
writeInstruction->address == (uint32_t) KnownRegisters::MGMT_SCRATCH_1
|
||||
|| (writeInstruction->address >= (uint32_t) KnownRegisters::BSM_SCRATCH_START &&
|
||||
writeInstruction->address < (uint32_t) KnownRegisters::BSM_SCRATCH_END)
|
||||
writeInstruction->address.address == (uint32_t) KnownRegisters::MGMT_SCRATCH_1
|
||||
|| (writeInstruction->address.address >= (uint32_t) KnownRegisters::BSM_SCRATCH_START &&
|
||||
writeInstruction->address.address < (uint32_t) KnownRegisters::BSM_SCRATCH_END)
|
||||
)
|
||||
&& writeInstruction->data.size() == 1
|
||||
) { //This is commonly used before jumps to mark return values or switch statements
|
||||
|
|
|
@ -52,6 +52,10 @@ std::string OutputContext::getComment(uint32_t location) const {
|
|||
return "";
|
||||
}
|
||||
|
||||
bool OutputContext::isNop(uint32_t location) const {
|
||||
return nop.find(location) != nop.end();
|
||||
}
|
||||
|
||||
|
||||
std::string OutputContext::getDataHeader(uint32_t location) const {
|
||||
std::stringstream s;
|
||||
|
@ -115,6 +119,9 @@ void OutputContext::analyze() {
|
|||
case JumpKind::Return:
|
||||
from << "Return";
|
||||
break;
|
||||
case JumpKind::Interrupt:
|
||||
from << "Interrupt";
|
||||
break;
|
||||
}
|
||||
from << "), ";
|
||||
} else {
|
||||
|
@ -147,7 +154,7 @@ void OutputContext::analyze() {
|
|||
if (writeInstruction.data.size() == 1 &&
|
||||
writeInstruction.data[0] == e.first) { //Return value!
|
||||
//TODO: mark join?
|
||||
addComment(writeInstruction.getAddress() + 4, locText);
|
||||
addComment(writeInstruction.getAddress() + 4, locText, true);
|
||||
foundReturn = true;
|
||||
break;
|
||||
}
|
||||
|
@ -169,7 +176,7 @@ void OutputContext::analyze() {
|
|||
}
|
||||
|
||||
if (e.second.size() > 1 || (!hasContinue && !e.second.empty())) {
|
||||
addComment(e.first, "<" + getLabel(e.first, true) + "> " + from.str());
|
||||
addComment(e.first, "<" + getLabel(e.first, true) + "> " + from.str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,19 +188,29 @@ void OutputContext::addMapping(uint32_t location, const std::string &name, bool
|
|||
}
|
||||
}
|
||||
|
||||
void OutputContext::addComment(uint32_t location, const std::string &comment) {
|
||||
void OutputContext::addComment(uint32_t location, const std::string &comment, bool force) {
|
||||
|
||||
if (comments.find(location) != comments.end()) {
|
||||
comments[location] = comment + " --- " + comments[location];
|
||||
comments[location] = force ? comment + " :: " + comments[location] : comments[location] + " :: " + comment;
|
||||
} else {
|
||||
comments[location] = comment;
|
||||
}
|
||||
}
|
||||
|
||||
void OutputContext::setNop(uint32_t location) {
|
||||
|
||||
nop[location] = true;
|
||||
}
|
||||
|
||||
std::string OutputContext::getAddressRegisterName(uint32_t addr, uint8_t offset) const {
|
||||
if (offset || registers.find(addr) == registers.end()) {
|
||||
uint64_t k = (uint64_t)addr | ((uint64_t)offset << 32);
|
||||
if (registers.find(k) == registers.end()) {
|
||||
return ::getAddressRegisterName(addr, offset);
|
||||
} else {
|
||||
return registers.at(addr);
|
||||
return registers.at(k);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputContext::addRegister(const Instruction::AddressWithOffset &address, const std::string &name) {
|
||||
registers[(uint64_t)address.address | ((uint64_t)address.offset << 32)] = name;
|
||||
}
|
||||
|
|
|
@ -41,21 +41,22 @@ private:
|
|||
const ImageFormat ℑ
|
||||
std::unordered_map<uint32_t, std::string> mappings;
|
||||
std::unordered_map<uint32_t, std::string> comments;
|
||||
std::unordered_map<uint32_t, std::string> registers;
|
||||
std::unordered_map<uint64_t, std::string> registers;
|
||||
std::unordered_map<uint32_t, bool> nop;
|
||||
|
||||
public:
|
||||
|
||||
OutputContext(const ImageFormat &image) : image(image) {
|
||||
explicit OutputContext(const ImageFormat &image) : image(image) {
|
||||
|
||||
}
|
||||
|
||||
void addMapping(uint32_t location, const std::string &name, bool force = false);
|
||||
|
||||
void addComment(uint32_t location, const std::string &comment);
|
||||
void addComment(uint32_t location, const std::string &comment, bool force = false);
|
||||
|
||||
void addRegister(uint32_t addr, const std::string &name) {
|
||||
registers[addr] = name;
|
||||
}
|
||||
void setNop(uint32_t location);
|
||||
|
||||
void addRegister(const Instruction::AddressWithOffset& address, const std::string &name);
|
||||
|
||||
std::string getAddressRegisterName(uint32_t addr, uint8_t offset) const;
|
||||
|
||||
|
@ -69,6 +70,8 @@ public:
|
|||
|
||||
std::string getDataHeader(uint32_t location) const;
|
||||
|
||||
bool isNop(uint32_t location) const;
|
||||
|
||||
std::string getDataEntry(uint32_t location, const std::string &representation = "") const;
|
||||
|
||||
std::string getInstructionString(const Instruction::Instruction &instruction) const;
|
||||
|
|
|
@ -64,6 +64,8 @@ std::string getRegisterName(KnownRegisters addr) {
|
|||
return "INTERRUPT_MASK_BSM";
|
||||
case KnownRegisters::CHIP_VERSION:
|
||||
return "CHIP_VERSION";
|
||||
case KnownRegisters::BSM_CTRL:
|
||||
return "BSM_CTRL";
|
||||
case KnownRegisters::BSM_ARGS:
|
||||
return "BSM_ARGS";
|
||||
case KnownRegisters::BSM_ADDR_OFFSET_0:
|
||||
|
|
|
@ -52,11 +52,17 @@ enum class KnownRegisters : uint32_t {
|
|||
|
||||
INTERRUPT_MASK_BSM = 0x442,
|
||||
|
||||
SRAM_ERR_IM_0 = 0x448,
|
||||
SRAM_ERR_IM_1 = 0x449,
|
||||
|
||||
SW_IM = 0x44E,
|
||||
|
||||
CHIP_VERSION = 0x452,
|
||||
|
||||
BSM_SCRATCH_START = 0x800,
|
||||
BSM_SCRATCH_END = BSM_SCRATCH_START + 0x400 - 1,
|
||||
|
||||
BSM_CTRL = 0x000C00,
|
||||
BSM_ARGS = 0x000C01,
|
||||
|
||||
BSM_ADDR_OFFSET_0 = 0x000C04,
|
||||
|
|
|
@ -180,7 +180,7 @@ Instruction::Calc::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Calc::toBytes() const {
|
||||
|
|
|
@ -179,7 +179,7 @@ Instruction::CalcImm::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::CalcImm::toBytes() const {
|
||||
|
|
|
@ -83,15 +83,15 @@ std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>
|
|||
Instruction::Copy::execute(AnalysisState &state) const {
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
state.setRegister(addressBB.offset + addressBB.address + i,
|
||||
state.getRegister(addressAA.offset + addressAA.address + i));
|
||||
state.setRegister(state.getAddressOffset(addressBB.offset) + addressBB.address + i,
|
||||
state.getRegister(state.getAddressOffset(addressAA.offset) + addressAA.address + i));
|
||||
}
|
||||
|
||||
state.current = _endAddress;
|
||||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,14 +52,14 @@ std::vector<Instruction::OutputFormat> Instruction::End::toOutputFormat(const Ou
|
|||
}
|
||||
|
||||
std::vector<uint32_t> Instruction::End::getPossibleBranches() const {
|
||||
return std::vector<uint32_t>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>
|
||||
Instruction::End::execute(AnalysisState &state) const {
|
||||
state.current = 0;
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::End::toBytes() const {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "../Registers.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "../OutputContext.h"
|
||||
|
||||
void Instruction::Init::fromBytes(uint32_t offset, const std::vector<uint8_t> &bytes) {
|
||||
_address = offset;
|
||||
|
@ -69,18 +70,35 @@ std::string Instruction::Init::toString() const {
|
|||
if (count > 1 && increment) {
|
||||
op << " UNTIL " << getAddressRegisterName(address + count - 1, addressOffset);
|
||||
}
|
||||
op << " COUNT " << std::hex << std::setw(6) << std::setfill('0') << count;
|
||||
op << " INCREMENT " << std::dec << (uint32_t) increment;
|
||||
op << " COUNT " << std::hex << std::setw(6) << std::setfill('0') << count;
|
||||
op << " DATA 0x" << std::hex << std::setw(8) << std::setfill('0') << data;
|
||||
op << " INC 0x" << std::hex << std::setw(8) << std::setfill('0') << data_add;
|
||||
op << " ADD 0x" << std::hex << std::setw(8) << std::setfill('0') << data_add;
|
||||
|
||||
return op.str();
|
||||
}
|
||||
|
||||
std::vector<Instruction::OutputFormat> Instruction::Init::toOutputFormat(const OutputContext &context) const {
|
||||
return std::vector<OutputFormat>{
|
||||
//TODO
|
||||
std::vector<OutputFormat> f{
|
||||
OutputFormat{getAddress() + 0 * 4,
|
||||
dynamic_cast<std::stringstream &>(std::stringstream("") << "INIT" << " "
|
||||
<< context.getAddressRegisterName(
|
||||
address, addressOffset)
|
||||
<< ", INC " << std::dec
|
||||
<< (uint32_t) increment).str()}
|
||||
};
|
||||
|
||||
f.emplace_back(OutputFormat{getAddress() + 1 * 4,
|
||||
dynamic_cast<std::stringstream &>(std::stringstream("") << " COUNT " << std::dec
|
||||
<< count).str()});
|
||||
|
||||
f.emplace_back(OutputFormat{getAddress() + 2 * 4,
|
||||
dynamic_cast<std::stringstream &>(std::stringstream("") << " DATA 0x" << std::hex << std::setw(8) << std::setfill('0') << data).str()});
|
||||
|
||||
f.emplace_back(OutputFormat{getAddress() + 3 * 4,
|
||||
dynamic_cast<std::stringstream &>(std::stringstream("") << " ADD 0x" << std::hex << std::setw(8) << std::setfill('0') << data_add).str()});
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> Instruction::Init::getPossibleBranches() const {
|
||||
|
@ -90,14 +108,14 @@ std::vector<uint32_t> Instruction::Init::getPossibleBranches() const {
|
|||
std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>
|
||||
Instruction::Init::execute(AnalysisState &state) const {
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
state.setRegister(address + (increment ? i : 0), data + data_add * i);
|
||||
state.setRegister(address + increment, data + data_add * i);
|
||||
}
|
||||
|
||||
state.current = _endAddress;
|
||||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Init::toBytes() const {
|
||||
|
|
|
@ -54,11 +54,11 @@ namespace Instruction {
|
|||
execute(AnalysisState &state) const override;
|
||||
|
||||
|
||||
uint8_t addressOffset;
|
||||
uint8_t increment;
|
||||
uint32_t address;
|
||||
uint32_t count;
|
||||
uint32_t data;
|
||||
uint32_t data_add;
|
||||
uint8_t addressOffset{};
|
||||
uint8_t increment{};
|
||||
uint32_t address{};
|
||||
uint32_t count{};
|
||||
uint32_t data{};
|
||||
uint32_t data_add{};
|
||||
};
|
||||
}
|
|
@ -48,6 +48,8 @@ namespace Instruction {
|
|||
uint32_t _endAddress{};
|
||||
public:
|
||||
|
||||
virtual ~Instruction()= default;
|
||||
|
||||
enum class CommandOp : uint8_t {
|
||||
WRITE = 0b00000000,
|
||||
COPY = 0b01000000,
|
||||
|
|
|
@ -70,7 +70,7 @@ Instruction::Jump::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(jumpAddress, getAddress(), JumpKind::Absolute);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Jump::toBytes() const {
|
||||
|
|
|
@ -182,7 +182,7 @@ std::vector<Instruction::OutputFormat> Instruction::Load::toOutputFormat(const O
|
|||
dynamic_cast<std::stringstream &>(std::stringstream("") << " "
|
||||
<< context.getAddressRegisterName(
|
||||
address +
|
||||
offset - 2,
|
||||
(increment ? offset - 2 : 0),
|
||||
addressOffset)
|
||||
<< " = 0x" << std::hex
|
||||
<< std::setw(8)
|
||||
|
@ -220,7 +220,7 @@ Instruction::Load::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Load::toBytes() const {
|
||||
|
|
|
@ -74,9 +74,9 @@ std::string Instruction::Poll::toString() const {
|
|||
op << "POLL IF (" << getAddressRegisterName(address) << " & 0x" << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << mask << ")";
|
||||
if (equality) {
|
||||
op << " != ";
|
||||
} else {
|
||||
op << " == ";
|
||||
} else {
|
||||
op << " != ";
|
||||
}
|
||||
op << "0x" << std::hex << std::setw(8) << std::setfill('0') << value << " WAIT " << std::dec << retryInterval
|
||||
<< " MAX " << std::dec << maxRetry << " EXCEED JUMP 0x" << std::hex << std::setw(6) << std::setfill('0')
|
||||
|
|
|
@ -63,7 +63,7 @@ std::vector<Instruction::OutputFormat> Instruction::Return::toOutputFormat(const
|
|||
}
|
||||
|
||||
std::vector<uint32_t> Instruction::Return::getPossibleBranches() const {
|
||||
return std::vector<uint32_t>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>
|
||||
|
@ -73,7 +73,7 @@ Instruction::Return::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(jumpAddress, getAddress(), JumpKind::Return);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ Instruction::Set::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Set::toBytes() const {
|
||||
|
|
|
@ -70,7 +70,7 @@ Instruction::Wait::execute(AnalysisState &state) const {
|
|||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Wait::toBytes() const {
|
||||
|
|
|
@ -36,12 +36,12 @@ void Instruction::Write::fromBytes(uint32_t offset, const std::vector<uint8_t> &
|
|||
|
||||
uint32_t command = bytes[offset++];
|
||||
|
||||
uint8_t count = (1 + (command >> 2) & 0b1111);
|
||||
addressOffset = command & 0b11;
|
||||
uint8_t count = (1 + ((command >> 2) & 0b1111));
|
||||
address.offset = command & 0b11;
|
||||
|
||||
address = bytes[offset++] << 16;
|
||||
address |= bytes[offset++] << 8;
|
||||
address |= bytes[offset++];
|
||||
address.address = bytes[offset++] << 16;
|
||||
address.address |= bytes[offset++] << 8;
|
||||
address.address |= bytes[offset++];
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
uint32_t entry = bytes[offset++] << 24;
|
||||
|
@ -57,7 +57,7 @@ void Instruction::Write::fromBytes(uint32_t offset, const std::vector<uint8_t> &
|
|||
|
||||
std::string Instruction::Write::toString() const {
|
||||
std::stringstream op;
|
||||
op << "WRITE " << getAddressRegisterName(address, addressOffset) << " = 0x";
|
||||
op << "WRITE " << getAddressRegisterName(address) << " = 0x";
|
||||
|
||||
for (auto d : data) {
|
||||
op << std::hex << std::setw(8) << std::setfill('0') << d;
|
||||
|
@ -71,8 +71,7 @@ std::vector<Instruction::OutputFormat> Instruction::Write::toOutputFormat(const
|
|||
std::vector<OutputFormat> f{
|
||||
OutputFormat{getAddress() + offset++ * 4,
|
||||
dynamic_cast<std::stringstream &>(std::stringstream("") << "WRITE" << " "
|
||||
<< context.getAddressRegisterName(
|
||||
address, addressOffset) << ", "
|
||||
<< context.getAddressRegisterName(address) << ", "
|
||||
<< std::dec
|
||||
<< (uint32_t) data.size()).str()}
|
||||
};
|
||||
|
@ -81,8 +80,7 @@ std::vector<Instruction::OutputFormat> Instruction::Write::toOutputFormat(const
|
|||
f.emplace_back(OutputFormat{getAddress() + offset * 4,
|
||||
dynamic_cast<std::stringstream &>(std::stringstream("") << " "
|
||||
<< context.getAddressRegisterName(
|
||||
address + offset -
|
||||
1, addressOffset)
|
||||
address.address + offset - 1, address.offset)
|
||||
<< " = 0x" << std::hex
|
||||
<< std::setw(8)
|
||||
<< std::setfill('0')
|
||||
|
@ -100,29 +98,27 @@ std::vector<uint32_t> Instruction::Write::getPossibleBranches() const {
|
|||
|
||||
std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>
|
||||
Instruction::Write::execute(AnalysisState &state) const {
|
||||
auto memoryOffset = state.getAddressOffset(addressOffset);
|
||||
auto memoryOffset = state.getAddressOffset(address.offset);
|
||||
|
||||
for (uint32_t i = 0; i < data.size(); ++i) {
|
||||
state.setRegister(memoryOffset + address + i, data[i]);
|
||||
state.setRegister(memoryOffset + address.address + i, data[i]);
|
||||
}
|
||||
|
||||
state.current = _endAddress;
|
||||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
state.addKnownJump(getEndAddress(), getAddress(), JumpKind::Continue);
|
||||
|
||||
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Instruction::Write::toBytes() const {
|
||||
std::vector<uint8_t> bytes;
|
||||
|
||||
bytes.emplace_back((uint8_t) getCommand() | ((data.size() - 1) << 2) | addressOffset);
|
||||
bytes.emplace_back((uint8_t) getCommand() | ((data.size() - 1) << 2) | address.offset);
|
||||
|
||||
bytes.emplace_back((address >> 16) & 0xFF);
|
||||
bytes.emplace_back((address >> 8) & 0xFF);
|
||||
bytes.emplace_back(address & 0xFF);
|
||||
bytes.emplace_back((address.address >> 16) & 0xFF);
|
||||
bytes.emplace_back((address.address >> 8) & 0xFF);
|
||||
bytes.emplace_back(address.address & 0xFF);
|
||||
|
||||
for (auto d : data) {
|
||||
bytes.emplace_back((d >> 24) & 0xFF);
|
||||
|
|
|
@ -55,9 +55,7 @@ namespace Instruction {
|
|||
std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>
|
||||
execute(AnalysisState &state) const override;
|
||||
|
||||
|
||||
uint8_t addressOffset;
|
||||
uint32_t address;
|
||||
AddressWithOffset address;
|
||||
std::vector<uint32_t> data;
|
||||
};
|
||||
}
|
234
src/main.cpp
234
src/main.cpp
|
@ -34,6 +34,24 @@
|
|||
#include "Registers.h"
|
||||
#include "instructions/Load.h"
|
||||
#include "OutputContext.h"
|
||||
#include "instructions/End.h"
|
||||
|
||||
|
||||
std::string ltrim(const std::string &s)
|
||||
{
|
||||
size_t start = s.find_first_not_of(" \n\r\t\f\v");
|
||||
return (start == std::string::npos) ? "" : s.substr(start);
|
||||
}
|
||||
|
||||
std::string rtrim(const std::string &s)
|
||||
{
|
||||
size_t end = s.find_last_not_of(" \n\r\t\f\v");
|
||||
return (end == std::string::npos) ? "" : s.substr(0, end + 1);
|
||||
}
|
||||
|
||||
std::string trim(const std::string &s) {
|
||||
return rtrim(ltrim(s));
|
||||
}
|
||||
|
||||
void decodeImage(const std::string &fileName) {
|
||||
|
||||
|
@ -46,7 +64,7 @@ void decodeImage(const std::string &fileName) {
|
|||
auto imageObject = ImageFormat::fromBytes(bytes);
|
||||
|
||||
|
||||
printf("SPEED: 0x%02x MODE: 0x%02x BOOT: 0x%08x\n", imageObject.getHeader().speed, imageObject.getHeader().mode,
|
||||
printf("SPEED: 0x%02x MODE: 0x%02x BOOT: 0x%08x\n", static_cast<uint32_t>(imageObject.getHeader().speed), static_cast<uint32_t>(imageObject.getHeader().mode),
|
||||
imageObject.getHeader().baseAddress);
|
||||
|
||||
std::cout << "SIGNATURE: " << imageObject.imageSignature << "\n";
|
||||
|
@ -193,27 +211,61 @@ void decodeImage(const std::string &fileName) {
|
|||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 10, "api_PEP_MAC_BASE"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 100, "api_CUSTOM_MAC_BASE"},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x0d9, "platform_FUNCTION_PCIeReset_enable"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x0da, "platform_FUNCTION_PCIeReset_disable"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x0db, "platform_FUNCTION_SERDES_InterruptCode_1"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x0dc, "platform_FUNCTION_SERDES_InterruptCode_0"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x12e, "param_SBUS_PCIE_REQUEST_-_SBUS_PCIE_RESPONSE"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x12f, "param_SBUS_PCIE_COMMAND_doRead"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x130, "param_SBUS_PCIE_COMMAND.DeviceAddress"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x131, "param_SBUS_PCIE_COMMAND.Register"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x132, "custom_param_RETURN_TO_SUCCESS"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x133, "custom_param_RETURN_TO_FAILURE"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x139, "custom_PEP_ADDR_OFFSET"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x13a, "custom_PEP_offset_PCIE_PORTLOGIC"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x13c, "custom_PEP_CONFIG_numberOfLanes"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x141, "custom_PEP_CONFIG_serial0"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x142, "custom_PEP_CONFIG_serial1"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x143, "custom_PEP_CONFIG_mgmtPep"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x144, "custom_PEP_CONFIG_vendor_device"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x145, "custom_PEP_CONFIG_subVendor_subDevice"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x145, "custom_PEP_CONFIG_gen"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x13c, "custom_PEP_CONFIG_numberOfLanes"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x17f, "custom_PEP_CONFIG_ASPMEnable"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x139, "custom_PEP_ADDR_OFFSET"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x154, "custom_PEP_NUMBER"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x12e, "param_SBUS_PCIE_REQUEST_-_SBUS_PCIE_RESPONSE"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x12f, "param_SBUS_PCIE_COMMAND_doWrite"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x130, "param_SBUS_PCIE_COMMAND.DeviceAddress"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x131, "param_SBUS_PCIE_COMMAND.Register"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x15a, "platform_PEP_skip_SRIOV_config"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x15b, "platform_PEP0_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x15c, "platform_PEP1_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x15d, "platform_PEP2_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x15e, "platform_PEP3_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x15f, "platform_PEP4_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x150, "platform_PEP5_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x151, "platform_PEP6_PCIE_CLK_CTRL"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x152, "platform_PEP7_PCIE_CLK_CTRL"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x164, "custom_PEP_CONFIG_gen"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x16b, "platform_PEP0_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x16c, "platform_PEP1_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x16d, "platform_PEP2_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x16e, "platform_PEP3_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x16f, "platform_PEP4_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x160, "platform_PEP5_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x161, "platform_PEP6_something_counter"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x162, "platform_PEP7_something_counter"},
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x17f, "custom_PEP_CONFIG_ASPMEnable"},
|
||||
|
||||
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x132, "custom_param_RETURN_TO_SUCCESS"},
|
||||
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x133, "custom_param_RETURN_TO_FAILURE"},
|
||||
|
||||
/**
|
||||
* api_BSM_STATUS: Step[0-7]
|
||||
|
@ -264,14 +316,6 @@ void decodeImage(const std::string &fileName) {
|
|||
|
||||
};
|
||||
|
||||
for (auto &e : knownNames) {
|
||||
ctx.addMapping(e.first, e.second);
|
||||
}
|
||||
|
||||
for (auto &c : comments) {
|
||||
ctx.addComment(c.first, c.second);
|
||||
}
|
||||
|
||||
for(uint32_t i = 10; i < 200; ++i){
|
||||
if(registerRename.find((uint32_t) KnownRegisters::BSM_SCRATCH_START + i) == registerRename.end()){
|
||||
std::stringstream s;
|
||||
|
@ -305,7 +349,145 @@ void decodeImage(const std::string &fileName) {
|
|||
}
|
||||
|
||||
for (auto &r : registerRename) {
|
||||
ctx.addRegister(r.first, r.second);
|
||||
ctx.addRegister(Instruction::AddressWithOffset{r.first, 0}, r.second);
|
||||
}
|
||||
|
||||
bool isKnownAssembler = false;
|
||||
if (imageObject.imageSignature.find("rrc-as") != std::string::npos) {
|
||||
//Known assembler
|
||||
isKnownAssembler = true;
|
||||
comments.clear();
|
||||
knownNames.clear();
|
||||
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_ADDR_OFFSET_3), 0}, "rrcc_STACK_POINTER");
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_ADDR_OFFSET_2), 0}, "rrcc_FRAME_POINTER");
|
||||
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::MGMT_SCRATCH_0), 0}, "rrcc_SCRATCH_0");
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::MGMT_SCRATCH_1), 0}, "rrcc_SCRATCH_1");
|
||||
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_SCRATCH_START) + 0x1E0, 0}, "rrcc_RETURN_VALUE");
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_SCRATCH_START) + 0x1E1, 0}, "rrcc_RETURN_VALUE_EXTRA");
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_SCRATCH_START) + 0x1E2, 0}, "rrcc_P0");
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_SCRATCH_START) + 0x1E3, 0}, "rrcc_P1");
|
||||
|
||||
for(uint32_t i = 0; i < 16; ++i){
|
||||
ctx.addRegister(Instruction::AddressWithOffset{i, 3}, "rrcc_STACK_POINTER+" +
|
||||
std::to_string(i));
|
||||
}
|
||||
for(uint32_t i = 0; i < 16; ++i){
|
||||
ctx.addRegister(Instruction::AddressWithOffset{i, 2}, "rrcc_FRAME_POINTER+" +
|
||||
std::to_string(i));
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < 16; ++i){
|
||||
ctx.addRegister(Instruction::AddressWithOffset{static_cast<uint32_t>(KnownRegisters::BSM_SCRATCH_START) + 0x1F0 + i, 0}, "rrcc_R" +
|
||||
std::to_string(i));
|
||||
}
|
||||
|
||||
|
||||
for (auto& i : imageObject.getInstructions()){
|
||||
std::unique_ptr<Instruction::Instruction> decodedInstruction = nullptr;
|
||||
std::unique_ptr<Instruction::Instruction> decodedInstruction2 = nullptr;
|
||||
const Instruction::End* endPointer = nullptr;
|
||||
if(i.second->getCommand() == Instruction::Instruction::CommandOp::END){
|
||||
endPointer = reinterpret_cast<const Instruction::End*>(i.second.get());
|
||||
if(endPointer->reserved == 0 || endPointer->reserved == 0xFFFFFF){
|
||||
endPointer = nullptr;
|
||||
}
|
||||
}
|
||||
if(endPointer == nullptr && imageObject.findConstInstructionByAddress(i.second->getEndAddress(), false) == nullptr){
|
||||
decodedInstruction = Instruction::Instruction::decodeInstructionFromBytes(i.second->getEndAddress(), imageObject.getBaseImage());
|
||||
if(decodedInstruction != nullptr && decodedInstruction->getCommand() == Instruction::Instruction::CommandOp::END){
|
||||
endPointer = reinterpret_cast<const Instruction::End*>(decodedInstruction.get());
|
||||
if(endPointer->reserved != endPointer->getAddress()){
|
||||
endPointer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(endPointer != nullptr){ //Found backwards pointer
|
||||
bool hasMore = true;
|
||||
|
||||
ctx.setNop(endPointer->getAddress());
|
||||
|
||||
uint32_t functionEnd = endPointer->reserved - 4;
|
||||
uint32_t nextAddress = endPointer->getEndAddress();
|
||||
|
||||
do{
|
||||
decodedInstruction2 = Instruction::Instruction::decodeInstructionFromBytes(nextAddress, imageObject.getBaseImage());
|
||||
if(decodedInstruction2 != nullptr && decodedInstruction2->getCommand() == Instruction::Instruction::CommandOp::LOAD){
|
||||
auto loadPointer = reinterpret_cast<const Instruction::Load&>(*decodedInstruction2);
|
||||
for(auto nopAddr = loadPointer.getAddress(); nopAddr < loadPointer.getEndAddress(); nopAddr += 4){
|
||||
ctx.setNop(nopAddr);
|
||||
}
|
||||
|
||||
uint32_t targetAddress = loadPointer.address;
|
||||
std::string stringData;
|
||||
for(auto& d : loadPointer.data){
|
||||
uint8_t c = ((d >> 24) & 0xFF);
|
||||
if(c == 0){
|
||||
break;
|
||||
}
|
||||
stringData.push_back(c);
|
||||
c = ((d >> 16) & 0xFF);
|
||||
if(c == 0){
|
||||
break;
|
||||
}
|
||||
stringData.push_back(c);
|
||||
c = ((d >> 8) & 0xFF);
|
||||
if(c == 0){
|
||||
break;
|
||||
}
|
||||
stringData.push_back(c);
|
||||
c = (d & 0xFF);
|
||||
if(c == 0){
|
||||
break;
|
||||
}
|
||||
stringData.push_back(c);
|
||||
}
|
||||
|
||||
switch (loadPointer.addressOffset) {
|
||||
case 0: //FunctionName
|
||||
knownNames[targetAddress] = stringData;
|
||||
break;
|
||||
case 1: //Comment
|
||||
std::string s = stringData;
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
while ((pos = s.find('\n')) != std::string::npos) {
|
||||
token = s.substr(0, pos);
|
||||
auto trimmed = trim(token);
|
||||
if(!trimmed.empty()){
|
||||
ctx.addComment(targetAddress, trimmed);
|
||||
}
|
||||
s.erase(0, pos + 1);
|
||||
}
|
||||
auto trimmed = trim(s);
|
||||
if(!trimmed.empty()){
|
||||
ctx.addComment(targetAddress, trimmed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
nextAddress = loadPointer.getEndAddress();
|
||||
|
||||
hasMore = loadPointer.increment == 1;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
} while (hasMore);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &e : knownNames) {
|
||||
ctx.addMapping(e.first, e.second);
|
||||
}
|
||||
|
||||
for (auto &c : comments) {
|
||||
ctx.addComment(c.first, c.second);
|
||||
}
|
||||
|
||||
ctx.analyze();
|
||||
|
@ -313,7 +495,9 @@ void decodeImage(const std::string &fileName) {
|
|||
uint32_t prevAddress = 0;
|
||||
for (const auto &entry : imageObject.getInstructions()) {
|
||||
const auto &instruction = entry.second;
|
||||
if (instruction->getAddress() < prevAddress) {
|
||||
if(ctx.isNop(instruction->getAddress())){
|
||||
continue;
|
||||
}else if (instruction->getAddress() < prevAddress) {
|
||||
std::cout << "========== DECODE ERROR? ========== " << std::hex << std::setw(8) << std::setfill('0')
|
||||
<< prevAddress << " - " << std::hex << std::setw(8) << std::setfill('0')
|
||||
<< instruction->getAddress() << "\n";
|
||||
|
@ -321,6 +505,10 @@ void decodeImage(const std::string &fileName) {
|
|||
(instruction->getAddress() - prevAddress) < 1024) {
|
||||
std::cout << "\n\n";
|
||||
for (uint32_t addr = prevAddress; addr < instruction->getAddress(); addr += 4) {
|
||||
if(ctx.isNop(addr)){
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream op;
|
||||
std::string printable;
|
||||
op << std::hex << std::setw(6) << std::setfill('0') << addr << " ";
|
||||
|
|
Loading…
Reference in a new issue