Apply formatting changes
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
DataHoarder 2020-12-29 02:32:31 +01:00
parent 2497c413ab
commit d6aac8ce1d
35 changed files with 292 additions and 142 deletions

View file

@ -34,7 +34,7 @@
#include "SmallFirmwareFormat.h"
#include "instructions/AddressOffset.h"
enum class JumpKind{
enum class JumpKind {
Continue,
Absolute,
Speculative,
@ -56,23 +56,25 @@ public:
SmallFirmwareFormat pciSerDesFirmware;
AnalysisJumpTable& jumpTable;
AnalysisJumpTable &jumpTable;
void addKnownJump(uint32_t to, uint32_t from, JumpKind kind){
if(jumpTable.find(to) == jumpTable.end()){
void addKnownJump(uint32_t to, uint32_t from, JumpKind kind) {
if (jumpTable.find(to) == jumpTable.end()) {
jumpTable[to] = std::vector<std::pair<uint32_t, JumpKind>>{{from, kind}};
}else if(std::find(jumpTable[to].begin(), jumpTable[to].end(), std::pair<uint32_t, JumpKind>(from, kind)) == jumpTable[to].end()){
} else if (std::find(jumpTable[to].begin(), jumpTable[to].end(), std::pair<uint32_t, JumpKind>(from, kind)) ==
jumpTable[to].end()) {
jumpTable[to].emplace_back(from, kind);
}
}
AnalysisState(uint32_t initial, AnalysisJumpTable& table) : current(initial), previous(0), jumpTable(table) {
AnalysisState(uint32_t initial, AnalysisJumpTable &table) : current(initial), previous(0), jumpTable(table) {
}
AnalysisState(const AnalysisState &oldState) : current(oldState.current), previous(oldState.previous),
memory(oldState.memory), pciSPICOFirmware(oldState.pciSPICOFirmware),
pciSerDesFirmware(oldState.pciSerDesFirmware), jumpTable(oldState.jumpTable) {
pciSerDesFirmware(oldState.pciSerDesFirmware),
jumpTable(oldState.jumpTable) {
}
@ -80,19 +82,19 @@ public:
return current == other.current && memory == other.memory;
}
void setRegister(const Instruction::AddressWithOffset& address, uint32_t value);
void setRegister(const Instruction::AddressWithOffset &address, uint32_t value);
void setRegister(uint32_t addr, uint32_t value) {
memory[addr] = value;
}
uint32_t getRegister(const Instruction::AddressWithOffset& address) const;
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);
}
uint32_t getAddressWithOffset(const Instruction::AddressWithOffset& address) const;
uint32_t getAddressWithOffset(const Instruction::AddressWithOffset &address) const;
uint32_t getAddressOffset(uint8_t offsetEntry) const;
};

View file

@ -204,7 +204,7 @@ void ImageFormat::decodeAnalyzeInstructionsAt(uint32_t offset) {
do {
if(jumpsUsed.find(state.current) != jumpsUsed.end() && !jumpsUsed[state.current]){
if (jumpsUsed.find(state.current) != jumpsUsed.end() && !jumpsUsed[state.current]) {
speculativeJumps++;
}
@ -234,7 +234,7 @@ void ImageFormat::decodeAnalyzeInstructionsAt(uint32_t offset) {
auto possibleBranches = instruction->execute(state);
if(jumpsUsed.find(state.current) != jumpsUsed.end() && !jumpsUsed[state.current]){
if (jumpsUsed.find(state.current) != jumpsUsed.end() && !jumpsUsed[state.current]) {
jumpsUsed.erase(state.current); //Clear to recognize a non-speculative jump
}
@ -312,7 +312,8 @@ void ImageFormat::decodeAnalyzeInstructionsAt(uint32_t offset) {
}
std::cerr << "Next state, branched states left: " << std::dec << savedStates.size()
<< /*", executed states: " << std::dec << createdStates.size() <<*/ ", speculative jumps: " << std::dec << speculativeJumps << ", total instructions decoded: "
<< /*", executed states: " << std::dec << createdStates.size() <<*/ ", speculative jumps: "
<< std::dec << speculativeJumps << ", total instructions decoded: "
<< std::dec << instructions.size() << "\n";
}
}

View file

@ -63,7 +63,8 @@ public:
void decodeAnalyzeInstructionsAt(uint32_t offset);
const std::unique_ptr<Instruction::Instruction> &findConstInstructionByAddress(uint32_t addr, bool indirect = false) const {
const std::unique_ptr<Instruction::Instruction> &
findConstInstructionByAddress(uint32_t addr, bool indirect = false) const {
if (instructions.find(addr) != instructions.end()) {
return instructions.find(addr)->second;
}
@ -121,7 +122,7 @@ public:
return instructions;
}
const auto& getJumpTable() const{
const auto &getJumpTable() const {
return jumpTable;
}

View file

@ -32,19 +32,20 @@
#include "instructions/Jump.h"
#include "Registers.h"
std::string OutputContext::getLabel(uint32_t location, bool force) const{
if(mappings.find(location) != mappings.end() && (!force || !mappings.at(location).empty())){
std::string OutputContext::getLabel(uint32_t location, bool force) const {
if (mappings.find(location) != mappings.end() && (!force || !mappings.at(location).empty())) {
return mappings.at(location);
}
if(force){
if (force) {
std::stringstream s;
s << "loc_" << std::hex << std::setw(6) << std::setfill('0') << location;
return s.str();
}
return "";
}
std::string OutputContext::getComment(uint32_t location) const{
if(comments.find(location) != comments.end()){
std::string OutputContext::getComment(uint32_t location) const {
if (comments.find(location) != comments.end()) {
return " ; " + comments.at(location);
}
@ -55,8 +56,8 @@ std::string OutputContext::getComment(uint32_t location) const{
std::string OutputContext::getDataHeader(uint32_t location) const {
std::stringstream s;
s << std::hex << std::setw(6) << std::setfill('0') << location << " ";
for(uint32_t i = location; i < location + 4; ++i){
s << std::hex << std::setw(2) << std::setfill('0') << (uint32_t)image.getBaseImage().at(i) << " ";
for (uint32_t i = location; i < location + 4; ++i) {
s << std::hex << std::setw(2) << std::setfill('0') << (uint32_t) image.getBaseImage().at(i) << " ";
}
s << " ";
return s.str();
@ -65,38 +66,38 @@ std::string OutputContext::getDataHeader(uint32_t location) const {
std::string OutputContext::getDataEntry(uint32_t location, const std::string &representation) const {
std::string result = getDataHeader(location) + representation;
uint32_t padLength = 64;
if(result.size() < padLength){
if (result.size() < padLength) {
result.append(padLength - result.size(), ' ');
}
result += getComment(location);
return result;
}
std::string OutputContext::getInstructionString(const Instruction::Instruction& instruction) const {
std::string OutputContext::getInstructionString(const Instruction::Instruction &instruction) const {
std::string output;
for(auto& l : instruction.toOutputFormat(*this)){
for (auto &l : instruction.toOutputFormat(*this)) {
output += getDataEntry(l.location, l.format) + "\n";
}
return output;
}
void OutputContext::analyze() {
const auto& table = image.getJumpTable();
const auto &table = image.getJumpTable();
for (auto& e : table){
for (auto &e : table) {
std::stringstream from;
from << "XREF.CallFrom: ";
bool hasContinue = false;
bool justAbsolute = true;
bool justReturn = true;
for(auto& j : e.second){
if(j.second != JumpKind::Return){
for (auto &j : e.second) {
if (j.second != JumpKind::Return) {
justReturn = false;
}
if(j.second != JumpKind::Absolute && j.second != JumpKind::Speculative){
if (j.second != JumpKind::Absolute && j.second != JumpKind::Speculative) {
justAbsolute = false;
}
if(j.second != JumpKind::Continue){
if (j.second != JumpKind::Continue) {
from << std::hex << std::setw(6) << std::setfill('0') << j.first << "(";
switch (j.second) {
case JumpKind::Speculative:
@ -121,26 +122,30 @@ void OutputContext::analyze() {
}
}
if(justReturn || justAbsolute){
if(!e.second.empty() && justReturn){
auto& instruction = image.findConstInstructionByAddress(e.first - 1, true);
if(instruction != nullptr && (instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP || instruction->getCommand() == Instruction::Instruction::CommandOp::RETURN)){
if (justReturn || justAbsolute) {
if (!e.second.empty() && justReturn) {
auto &instruction = image.findConstInstructionByAddress(e.first - 1, true);
if (instruction != nullptr && (instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP ||
instruction->getCommand() ==
Instruction::Instruction::CommandOp::RETURN)) {
std::string locText = "RETURN location for call";
bool foundReturn = false;
uint32_t addressLocation = instruction->getAddress() - 1;
if(instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP){
auto& jumpInstruction = dynamic_cast<const Instruction::Jump&>(*instruction);
if (instruction->getCommand() == Instruction::Instruction::CommandOp::JUMP) {
auto &jumpInstruction = dynamic_cast<const Instruction::Jump &>(*instruction);
locText = "RETURN location for " + getLabel(jumpInstruction.jumpAddress);
}
while (true){
auto& instructionBefore = image.findConstInstructionByAddress(addressLocation, true);
if(instructionBefore != nullptr && instructionBefore->getCommand() == Instruction::Instruction::CommandOp::WRITE){
auto& writeInstruction = dynamic_cast<const Instruction::Write&>(*instructionBefore);
if(writeInstruction.data.size() == 1 && writeInstruction.data[0] == e.first){ //Return value!
while (true) {
auto &instructionBefore = image.findConstInstructionByAddress(addressLocation, true);
if (instructionBefore != nullptr &&
instructionBefore->getCommand() == Instruction::Instruction::CommandOp::WRITE) {
auto &writeInstruction = dynamic_cast<const Instruction::Write &>(*instructionBefore);
if (writeInstruction.data.size() == 1 &&
writeInstruction.data[0] == e.first) { //Return value!
//TODO: mark join?
addComment(writeInstruction.getAddress() + 4, locText);
foundReturn = true;
@ -152,18 +157,18 @@ void OutputContext::analyze() {
}
}
if(!foundReturn){
if (!foundReturn) {
addMapping(e.first, getLabel(e.first, true));
}
}else{
} else {
addMapping(e.first, getLabel(e.first, true));
}
}else{
} else {
addMapping(e.first, getLabel(e.first, true));
}
}
if(e.second.size() > 1 || (!hasContinue && !e.second.empty())){
if (e.second.size() > 1 || (!hasContinue && !e.second.empty())) {
addComment(e.first, "<" + getLabel(e.first, true) + "> " + from.str());
}
}
@ -171,16 +176,16 @@ void OutputContext::analyze() {
}
void OutputContext::addMapping(uint32_t location, const std::string &name, bool force) {
if(mappings.find(location) == comments.end() || (force && !mappings[location].empty())) {
if (mappings.find(location) == comments.end() || (force && !mappings[location].empty())) {
mappings[location] = name;
}
}
void OutputContext::addComment(uint32_t location, const std::string &comment) {
if(comments.find(location) != comments.end()){
if (comments.find(location) != comments.end()) {
comments[location] = comment + " --- " + comments[location];
}else{
} else {
comments[location] = comment;
}
}

View file

@ -38,28 +38,28 @@ class OutputContext {
public:
private:
const ImageFormat& image;
const ImageFormat &image;
std::unordered_map<uint32_t, std::string> mappings;
std::unordered_map<uint32_t, std::string> comments;
std::unordered_map<uint32_t, std::string> registers;
public:
OutputContext(const ImageFormat& image) : image(image){
OutputContext(const ImageFormat &image) : image(image) {
}
void addMapping(uint32_t location, const std::string& name, bool force = false);
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);
void addRegister(uint32_t addr, const std::string& name){
void addRegister(uint32_t addr, const std::string &name) {
registers[addr] = name;
}
std::string getAddressRegisterName(uint32_t addr, uint8_t offset) const ;
std::string getAddressRegisterName(uint32_t addr, uint8_t offset) const;
std::string getAddressRegisterName(const Instruction::AddressWithOffset& address) const {
std::string getAddressRegisterName(const Instruction::AddressWithOffset &address) const {
return getAddressRegisterName(address.address, address.offset);
}
@ -69,9 +69,9 @@ public:
std::string getDataHeader(uint32_t location) const;
std::string getDataEntry(uint32_t location, const std::string& representation = "") const;
std::string getDataEntry(uint32_t location, const std::string &representation = "") const;
std::string getInstructionString(const Instruction::Instruction& instruction) const;
std::string getInstructionString(const Instruction::Instruction &instruction) const;
void analyze();
};

View file

@ -180,7 +180,7 @@ std::string getAddressRegisterName(uint32_t addr, uint8_t offset) {
return s.str();
}
std::string getAddressRegisterName(const Instruction::AddressWithOffset& address) {
std::string getAddressRegisterName(const Instruction::AddressWithOffset &address) {
return getAddressRegisterName(address.address, address.offset);
}

View file

@ -126,4 +126,5 @@ KnownRegisters getScratchRegister(uint32_t offset);
std::string getRegisterName(KnownRegisters addr);
std::string getAddressRegisterName(uint32_t addr, uint8_t offset = 0);
std::string getAddressRegisterName(const Instruction::AddressWithOffset& address);
std::string getAddressRegisterName(const Instruction::AddressWithOffset &address);

View file

@ -80,10 +80,23 @@ std::string Instruction::Branch::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Branch::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "BRANCH" << " " << context.getAddressRegisterName(address) << (equality ? " == " : " != ")).str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " VALUE 0x" << std::hex << std::setw(8) << std::setfill('0') << value).str()},
OutputFormat{getAddress() + 8, dynamic_cast<std::stringstream&>(std::stringstream("") << " MASK 0x" << std::hex << std::setw(8) << std::setfill('0') << mask).str()},
OutputFormat{getAddress() + 12, dynamic_cast<std::stringstream&>(std::stringstream("") << " JUMP_ADDRESS <" << context.getLabel(jumpAddress) << ">").str()},
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(std::stringstream("") << "BRANCH" << " "
<< context.getAddressRegisterName(
address)
<< (equality ? " == "
: " != ")).str()},
OutputFormat{getAddress() + 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " VALUE 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< value).str()},
OutputFormat{getAddress() + 8,
dynamic_cast<std::stringstream &>(std::stringstream("") << " MASK 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< mask).str()},
OutputFormat{getAddress() + 12,
dynamic_cast<std::stringstream &>(std::stringstream("") << " JUMP_ADDRESS <"
<< context.getLabel(jumpAddress)
<< ">").str()},
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -123,9 +123,18 @@ std::vector<Instruction::OutputFormat> Instruction::Calc::toOutputFormat(const O
}
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(opname << " " << context.getAddressRegisterName(addressDestination, addressOffset) << " = ").str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " SOURCE " << context.getAddressRegisterName(addressSource, addressOffset)).str()},
OutputFormat{getAddress() + 8, dynamic_cast<std::stringstream&>(std::stringstream("") << " TARGET " << context.getAddressRegisterName(addressTarget, addressOffset)).str()},
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(opname << " "
<< context.getAddressRegisterName(
addressDestination,
addressOffset) << " = ").str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream &>(std::stringstream("") << " SOURCE "
<< context.getAddressRegisterName(
addressSource,
addressOffset)).str()},
OutputFormat{getAddress() + 8, dynamic_cast<std::stringstream &>(std::stringstream("") << " TARGET "
<< context.getAddressRegisterName(
addressTarget,
addressOffset)).str()},
};
}

View file

@ -57,7 +57,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -123,9 +123,18 @@ std::vector<Instruction::OutputFormat> Instruction::CalcImm::toOutputFormat(cons
}
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(opname << "_IMM " << context.getAddressRegisterName(addressDestination, addressOffset) << " = ").str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " SOURCE " << context.getAddressRegisterName(addressSource, addressOffset)).str()},
OutputFormat{getAddress() + 8, dynamic_cast<std::stringstream&>(std::stringstream("") << " TARGET 0x" << std::hex << std::setw(8) << std::setfill('0') << value).str()},
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(opname << "_IMM "
<< context.getAddressRegisterName(
addressDestination,
addressOffset) << " = ").str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream &>(std::stringstream("") << " SOURCE "
<< context.getAddressRegisterName(
addressSource,
addressOffset)).str()},
OutputFormat{getAddress() + 8,
dynamic_cast<std::stringstream &>(std::stringstream("") << " TARGET 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< value).str()},
};
}

View file

@ -47,7 +47,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -64,8 +64,14 @@ std::string Instruction::Copy::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Copy::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "COPY" << " " << std::dec << (uint32_t)count << ", " << context.getAddressRegisterName(addressAA)).str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " TO " << context.getAddressRegisterName(addressBB)).str()}
OutputFormat{getAddress(),
dynamic_cast<std::stringstream &>(std::stringstream("") << "COPY" << " " << std::dec
<< (uint32_t) count << ", "
<< context.getAddressRegisterName(
addressAA)).str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream &>(std::stringstream("") << " TO "
<< context.getAddressRegisterName(
addressBB)).str()}
};
}
@ -77,7 +83,8 @@ 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(addressBB.offset + addressBB.address + i,
state.getRegister(addressAA.offset + addressAA.address + i));
}
state.current = _endAddress;

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -37,7 +37,7 @@
class OutputContext;
namespace Instruction {
typedef struct{
typedef struct {
uint32_t location;
std::string format;
} OutputFormat;
@ -75,7 +75,8 @@ namespace Instruction {
virtual std::vector<uint8_t> toBytes() const = 0;
virtual std::string toString() const = 0;
virtual std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const = 0;
virtual std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const = 0;
virtual std::vector<uint32_t> getPossibleBranches() const = 0;

View file

@ -53,7 +53,10 @@ std::string Instruction::Jump::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Jump::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "JUMP" << " <" << context.getLabel(jumpAddress) << ">").str()}
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(std::stringstream("") << "JUMP" << " <"
<< context.getLabel(
jumpAddress)
<< ">").str()}
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -118,13 +118,21 @@ std::vector<Instruction::OutputFormat> Instruction::Load::toOutputFormat(const O
uint32_t offset = 0;
std::vector<OutputFormat> f{
OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << "LOAD" << " PCIE_MASTER_SPICO_FIRMWARE").str()}
OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << "LOAD"
<< " PCIE_MASTER_SPICO_FIRMWARE").str()}
};
f.emplace_back(OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " COUNT " << std::dec << data.size()).str()});
f.emplace_back(OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " COUNT " << std::dec
<< data.size()).str()});
for (auto d : data) {
f.emplace_back(OutputFormat{getAddress() + offset * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " 0x" << std::hex << std::setw(8) << std::setfill('0') << d).str()});
f.emplace_back(OutputFormat{getAddress() + offset * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " 0x" << std::hex
<< std::setw(8)
<< std::setfill('0')
<< d).str()});
offset++;
}
@ -134,28 +142,52 @@ std::vector<Instruction::OutputFormat> Instruction::Load::toOutputFormat(const O
uint32_t offset = 0;
std::vector<OutputFormat> f{
OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << "LOAD" << " PCIE_BROADCAST_SERDES_FIRMWARE").str()},
OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << "LOAD"
<< " PCIE_BROADCAST_SERDES_FIRMWARE").str()},
};
f.emplace_back(OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " COUNT " << std::dec << data.size()).str()});
f.emplace_back(OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " COUNT " << std::dec
<< data.size()).str()});
for (auto d : data) {
f.emplace_back(OutputFormat{getAddress() + offset * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " 0x" << std::hex << std::setw(8) << std::setfill('0') << d).str()});
f.emplace_back(OutputFormat{getAddress() + offset * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " 0x" << std::hex
<< std::setw(8)
<< std::setfill('0')
<< d).str()});
offset++;
}
return f;
}else{
} else {
uint32_t offset = 0;
std::vector<OutputFormat> f{
OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << "LOAD" << " " << context.getAddressRegisterName(address, addressOffset) << ", INC " << std::dec << (uint32_t)increment).str()}
OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << "LOAD" << " "
<< context.getAddressRegisterName(
address, addressOffset)
<< ", INC " << std::dec
<< (uint32_t) increment).str()}
};
f.emplace_back(OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " COUNT " << std::dec << data.size()).str()});
f.emplace_back(OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " COUNT " << std::dec
<< data.size()).str()});
for (auto d : data) {
f.emplace_back(OutputFormat{getAddress() + offset * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " " << context.getAddressRegisterName(address + offset - 2, addressOffset) << " = 0x" << std::hex << std::setw(8) << std::setfill('0') << d).str()});
f.emplace_back(OutputFormat{getAddress() + offset * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " "
<< context.getAddressRegisterName(
address +
offset - 2,
addressOffset)
<< " = 0x" << std::hex
<< std::setw(8)
<< std::setfill('0')
<< d).str()});
offset++;
}
@ -190,6 +222,7 @@ Instruction::Load::execute(AnalysisState &state) const {
return std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>>();
}
std::vector<uint8_t> Instruction::Load::toBytes() const {
std::vector<uint8_t> bytes;

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -55,7 +55,14 @@ std::string Instruction::Loop::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Loop::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "LOOP" << " " << context.getAddressRegisterName((uint32_t) KnownRegisters::BSM_COUNTER_0 + counter, 0) << ", <" << context.getLabel(jumpAddress) << ">").str()},
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(std::stringstream("") << "LOOP" << " "
<< context.getAddressRegisterName(
(uint32_t) KnownRegisters::BSM_COUNTER_0 +
counter, 0)
<< ", <"
<< context.getLabel(
jumpAddress)
<< ">").str()},
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -87,11 +87,27 @@ std::string Instruction::Poll::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Poll::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "POLL" << " " << context.getAddressRegisterName(address) << (equality ? " == " : " != ")).str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " VALUE 0x" << std::hex << std::setw(8) << std::setfill('0') << value).str()},
OutputFormat{getAddress() + 8, dynamic_cast<std::stringstream&>(std::stringstream("") << " MASK 0x" << std::hex << std::setw(8) << std::setfill('0') << mask).str()},
OutputFormat{getAddress() + 12, dynamic_cast<std::stringstream&>(std::stringstream("") << " RETRY MAX " << std::dec << maxRetry << " INTERVAL " << std::dec << retryInterval).str()},
OutputFormat{getAddress() + 16, dynamic_cast<std::stringstream&>(std::stringstream("") << " JUMP_ADDRESS <" << context.getLabel(jumpAddress) << ">").str()},
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(std::stringstream("") << "POLL" << " "
<< context.getAddressRegisterName(
address)
<< (equality ? " == "
: " != ")).str()},
OutputFormat{getAddress() + 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " VALUE 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< value).str()},
OutputFormat{getAddress() + 8,
dynamic_cast<std::stringstream &>(std::stringstream("") << " MASK 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< mask).str()},
OutputFormat{getAddress() + 12,
dynamic_cast<std::stringstream &>(std::stringstream("") << " RETRY MAX " << std::dec
<< maxRetry << " INTERVAL " << std::dec
<< retryInterval).str()},
OutputFormat{getAddress() + 16,
dynamic_cast<std::stringstream &>(std::stringstream("") << " JUMP_ADDRESS <"
<< context.getLabel(jumpAddress)
<< ">").str()},
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -55,7 +55,10 @@ std::string Instruction::Return::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Return::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "RETURN" << " [" << context.getAddressRegisterName(address) << "]").str()}
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(std::stringstream("") << "RETURN" << " ["
<< context.getAddressRegisterName(
address)
<< "]").str()}
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -66,9 +66,17 @@ std::string Instruction::Set::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Set::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "SET" << " " << context.getAddressRegisterName(address)).str()},
OutputFormat{getAddress() + 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " VALUE 0x" << std::hex << std::setw(8) << std::setfill('0') << value).str()},
OutputFormat{getAddress() + 8, dynamic_cast<std::stringstream&>(std::stringstream("") << " MASK 0x" << std::hex << std::setw(8) << std::setfill('0') << mask).str()}
OutputFormat{getAddress(), dynamic_cast<std::stringstream &>(std::stringstream("") << "SET" << " "
<< context.getAddressRegisterName(
address)).str()},
OutputFormat{getAddress() + 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " VALUE 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< value).str()},
OutputFormat{getAddress() + 8,
dynamic_cast<std::stringstream &>(std::stringstream("") << " MASK 0x" << std::hex
<< std::setw(8) << std::setfill('0')
<< mask).str()}
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -52,7 +52,9 @@ std::string Instruction::Wait::toString() const {
std::vector<Instruction::OutputFormat> Instruction::Wait::toOutputFormat(const OutputContext &context) const {
return std::vector<OutputFormat>{
OutputFormat{getAddress(), dynamic_cast<std::stringstream&>(std::stringstream("") << "WAIT" << " " << std::dec << time).str()}
OutputFormat{getAddress(),
dynamic_cast<std::stringstream &>(std::stringstream("") << "WAIT" << " " << std::dec
<< time).str()}
};
}

View file

@ -45,7 +45,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -69,11 +69,24 @@ std::vector<Instruction::OutputFormat> Instruction::Write::toOutputFormat(const
uint32_t offset = 0;
std::vector<OutputFormat> f{
OutputFormat{getAddress() + offset++ * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << "WRITE" << " " << context.getAddressRegisterName(address, addressOffset) << ", " << std::dec << (uint32_t ) data.size()).str()}
OutputFormat{getAddress() + offset++ * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << "WRITE" << " "
<< context.getAddressRegisterName(
address, addressOffset) << ", "
<< std::dec
<< (uint32_t) data.size()).str()}
};
for (auto d : data) {
f.emplace_back(OutputFormat{getAddress() + offset * 4, dynamic_cast<std::stringstream&>(std::stringstream("") << " " << context.getAddressRegisterName(address + offset - 1, addressOffset) << " = 0x" << std::hex << std::setw(8) << std::setfill('0') << d).str()});
f.emplace_back(OutputFormat{getAddress() + offset * 4,
dynamic_cast<std::stringstream &>(std::stringstream("") << " "
<< context.getAddressRegisterName(
address + offset -
1, addressOffset)
<< " = 0x" << std::hex
<< std::setw(8)
<< std::setfill('0')
<< d).str()});
offset++;
}

View file

@ -47,7 +47,8 @@ namespace Instruction {
std::vector<uint8_t> toBytes() const override;
std::string toString() const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext& context) const override;
std::vector<OutputFormat> toOutputFormat(const OutputContext &context) const override;
std::vector<uint32_t> getPossibleBranches() const override;

View file

@ -58,10 +58,8 @@ void decodeImage(const std::string &fileName) {
OutputContext ctx(imageObject);
std::unordered_map<uint32_t, std::string> knownNames{
{imageObject.getHeader().baseAddress, "__ENTRYPOINT"},
{0x1000, "load_bootCfg_pep_serialNumber"},
{0x1054, "load_bootCfg_customMac"},
{0x1000, "load_bootCfg_pep_serialNumber"},
{0x1054, "load_bootCfg_customMac"},
{0x080600, "config_systimeClockSource"},
{0x080700, "config_startClocks"},
@ -69,6 +67,7 @@ void decodeImage(const std::string &fileName) {
{0x080900, "config_pcie_pep_enable"},
{0x083000, "config_?serdes?_pep"},
{0x084000, "reset_BSM_ARGS_init__ENTRYPOINT"},
{0x085a0c, "config_pep0_offsets"},
@ -157,6 +156,8 @@ void decodeImage(const std::string &fileName) {
{0x0893b0, "loc_0893b0_load_config_unknown_1"}
};
knownNames[imageObject.getHeader().baseAddress] = "__ENTRYPOINT";
std::unordered_map<uint32_t, std::string> comments{
{0x080260, "Setting BSM_ARGS means this will be called again when reset, BSM_SCRATCH[0x149] is set to ~ 084000"},
{0x084000, "XREF From BSM_ARGS"},
@ -173,41 +174,41 @@ void decodeImage(const std::string &fileName) {
};
std::unordered_map<uint32_t, std::string> registerRename{
{(uint32_t)KnownRegisters::MGMT_SCRATCH_0, "custom_RETURN_VALUE"},
{(uint32_t)KnownRegisters::MGMT_SCRATCH_1, "custom_RETURN_TO"},
{(uint32_t) KnownRegisters::MGMT_SCRATCH_0, "custom_RETURN_VALUE"},
{(uint32_t) KnownRegisters::MGMT_SCRATCH_1, "custom_RETURN_TO"},
{(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 + 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 + 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 + 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 + 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 + 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 + 0x132, "custom_param_RETURN_TO_SUCCESS"},
{(uint32_t)KnownRegisters::BSM_SCRATCH_START + 0x133, "custom_param_RETURN_TO_FAILURE"},
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x132, "custom_param_RETURN_TO_SUCCESS"},
{(uint32_t) KnownRegisters::BSM_SCRATCH_START + 0x133, "custom_param_RETURN_TO_FAILURE"},
};
for(auto& e : knownNames){
for (auto &e : knownNames) {
ctx.addMapping(e.first, e.second);
}
for(auto& c : comments){
for (auto &c : comments) {
ctx.addComment(c.first, c.second);
}
for(auto& r : registerRename){
for (auto &r : registerRename) {
ctx.addRegister(r.first, r.second);
}
@ -245,8 +246,9 @@ void decodeImage(const std::string &fileName) {
<< "\n";
}
if(!ctx.getLabel(instruction->getAddress(), false).empty()){
std::cout << "\n\n; ================ FUNCTION " << ctx.getLabel(instruction->getAddress()) << " ================\n";
if (!ctx.getLabel(instruction->getAddress(), false).empty()) {
std::cout << "\n\n; ================ FUNCTION " << ctx.getLabel(instruction->getAddress())
<< " ================\n";
}
std::cout << ctx.getInstructionString(*instruction);
@ -418,7 +420,7 @@ patchImage(const std::string &originalImage, const std::string &settingsFile, co
if (entry.type == Configuration::ConfigurationNode::Type::ValueText &&
!entry.value.empty()) {
auto value = entry.getEUI64ToInteger();
if(value.first == 0xFFFFFFFF && value.second == 0xFFFFFFFF){
if (value.first == 0xFFFFFFFF && value.second == 0xFFFFFFFF) {
value.first &= 0xFF000100 | pepOffset;
value.second &= 0x000000FF;
}
@ -444,7 +446,7 @@ patchImage(const std::string &originalImage, const std::string &settingsFile, co
if (entry.type == Configuration::ConfigurationNode::Type::ValueText &&
!entry.value.empty()) {
auto value = entry.getEUI64ToInteger();
if(value.first == 0xFFFFFFFF && value.second == 0xFFFFFFFF){
if (value.first == 0xFFFFFFFF && value.second == 0xFFFFFFFF) {
value.first &= 0xFF000100 | customMacOffset;
value.second &= 0x000000FF;
}