Added decoding known mappings
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2020-12-28 22:13:48 +01:00
parent 88e7f0d8b8
commit 596aaabb6e
4 changed files with 132 additions and 13 deletions

View file

@ -28,6 +28,8 @@
#include <sstream>
#include <iomanip>
#include "OutputContext.h"
#include "instructions/Write.h"
#include "instructions/Jump.h"
std::string OutputContext::getLabel(uint32_t location, bool force) const{
if(mappings.find(location) != mappings.end()){
@ -35,7 +37,7 @@ std::string OutputContext::getLabel(uint32_t location, bool force) const{
}
if(force){
std::stringstream s;
s << "func_" << std::hex << std::setw(6) << std::setfill('0') << location;
s << "loc_" << std::hex << std::setw(6) << std::setfill('0') << location;
return s.str();
}
return "";
@ -60,7 +62,13 @@ std::string OutputContext::getDataHeader(uint32_t location) const {
}
std::string OutputContext::getDataEntry(uint32_t location, const std::string &representation) const {
return getDataHeader(location) + representation + getComment(location);
std::string result = getDataHeader(location) + representation;
uint32_t padLength = 64;
if(result.size() < padLength){
result.append(padLength - result.size(), ' ');
}
result += getComment(location);
return result;
}
std::string OutputContext::getInstructionString(const Instruction::Instruction& instruction) const {
@ -78,11 +86,15 @@ void OutputContext::analyze() {
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){
justReturn = false;
}
if(j.second != JumpKind::Absolute){
justAbsolute = false;
}
if(j.second != JumpKind::Continue){
from << std::hex << std::setw(6) << std::setfill('0') << j.first << "(";
switch (j.second) {
@ -104,11 +116,34 @@ void OutputContext::analyze() {
hasContinue = true;
}
}
if(!hasContinue){
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){
//TODO, mark join?
auto& jumpInstruction = dynamic_cast<const Instruction::Jump&>(*instruction);
bool foundReturn = false;
uint32_t addressLocation = instruction->getAddress() - 1;
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, "RETURN location for " + getLabel(jumpInstruction.jumpAddress));
foundReturn = true;
break;
}
addressLocation = instructionBefore->getAddress() - 1;
} else {
break;
}
}
if(!foundReturn){
addMapping(e.first, getLabel(e.first, true));
}
}else{
addMapping(e.first, getLabel(e.first, true));
}
@ -116,8 +151,9 @@ void OutputContext::analyze() {
addMapping(e.first, getLabel(e.first, true));
}
}
if(e.second.size() > 1 || (!hasContinue && !e.second.empty())){
addComment(e.first, from.str());
addComment(e.first, "<" + getLabel(e.first, true) + "> " + from.str());
}
}

View file

@ -48,8 +48,8 @@ public:
}
void addMapping(uint32_t location, const std::string& name){
if(comments.find(location) == comments.end()) {
void addMapping(uint32_t location, const std::string& name, bool force = false){
if(force || comments.find(location) == comments.end()) {
mappings[location] = name;
}
}

View file

@ -124,7 +124,7 @@ std::vector<Instruction::OutputFormat> Instruction::Load::toOutputFormat(const O
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++;
}
@ -140,7 +140,7 @@ std::vector<Instruction::OutputFormat> Instruction::Load::toOutputFormat(const O
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++;
}
@ -155,7 +155,7 @@ std::vector<Instruction::OutputFormat> Instruction::Load::toOutputFormat(const O
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("") << " " << 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("") << " " << getAddressRegisterName(address + offset - 2, addressOffset) << " = 0x" << std::hex << std::setw(8) << std::setfill('0') << d).str()});
offset++;
}

View file

@ -56,13 +56,96 @@ 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"},
{0x088000, "load_bootCfg_pep0_vpd"},
{0x0881c7, "load_bootCfg_pep1_vpd"},
{0x08838e, "load_bootCfg_pep2_vpd"},
{0x088555, "load_bootCfg_pep3_vpd"},
{0x08871c, "load_bootCfg_pep4_vpd"},
{0x0888e3, "load_bootCfg_pep5_vpd"},
{0x088aaa, "load_bootCfg_pep6_vpd"},
{0x088c71, "load_bootCfg_pep7_vpd"},
{0x088e38, "load_bootCfg_pep8_vpd"},
{0x089000, "load_bootCfg_systimeClockSource"},
{0x089010, "load_bootCfg_pep0_mode"},
{0x089020, "load_bootCfg_pep2_mode"},
{0x089030, "load_bootCfg_pep4_mode"},
{0x089040, "load_bootCfg_pep6_mode"},
{0x089050, "load_bootCfg_pep0_enable"},
{0x089060, "load_bootCfg_pep1_enable"},
{0x089070, "load_bootCfg_pep2_enable"},
{0x089080, "load_bootCfg_pep3_enable"},
{0x089090, "load_bootCfg_pep4_enable"},
{0x0890a0, "load_bootCfg_pep5_enable"},
{0x0890b0, "load_bootCfg_pep6_enable"},
{0x0890c0, "load_bootCfg_pep7_enable"},
{0x0890d0, "load_bootCfg_pep8_enable"},
{0x0890e0, "load_bootCfg_GPIO_PIN14_DRIVE"},
{0x0890f0, "load_bootCfg_spiTransferMode"},
{0x089100, "load_bootCfg_spiTransferSpeed"},
{0x089130, "load_bootCfg_pep_numberOfLanes"},
{0x0891f0, "load_bootCfg_pep_mgmtPep"},
{0x089230, "load_bootCfg_pep_vendor_device"},
{0x089260, "load_bootCfg_pep_subVendor_subDevice"},
{0x0892f0, "load_bootCfg_pep_gen"},
{0x089380, "load_bootCfg_pep_ASPMEnable"},
{0x083900, "execute_SerialBus_PCIE_Command"},
{0x080b00, "mark_SOFT_RESET_ClocksStable_ColdReset"},
{0x081100, "init_MASTER_SPICO"},
{0x08a004, "load_MASTER_SPICO_FW"},
{0x081400, "init_SERDES"},
{0x08c004, "load_SERDES_FW"},
//Merge function
{0x080004, ""},
{0x080008, ""},
{0x08000c, ""},
{0x08001c, ""},
{0x080038, ""},
{0x080068, ""},
{0x0870c4, ""},
};
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"}
};
for(auto& e : knownNames){
ctx.addMapping(e.first, e.second);
}
for(auto& c : comments){
ctx.addComment(c.first, c.second);
}
ctx.analyze();
uint32_t prevAddress = 0;
for (const auto &entry : imageObject.getInstructions()) {
const auto &instruction = entry.second;
if (instruction->getAddress() < prevAddress) {
std::cout << "====== DECODE ERROR? ========== " << std::hex << std::setw(8) << std::setfill('0')
std::cout << "========== DECODE ERROR? ========== " << std::hex << std::setw(8) << std::setfill('0')
<< prevAddress << " - " << std::hex << std::setw(8) << std::setfill('0')
<< instruction->getAddress() << "\n";
} else if ((instruction->getAddress() - prevAddress) >= 4 &&
@ -85,13 +168,13 @@ void decodeImage(const std::string &fileName) {
std::cout << op.str();
}
} else if ((instruction->getAddress() - prevAddress) >= 1024) {
std::cout << "================ " << std::hex << std::setw(8) << std::setfill('0') << prevAddress
std::cout << "\n\n================ " << std::hex << std::setw(8) << std::setfill('0') << prevAddress
<< " - " << std::hex << std::setw(8) << std::setfill('0') << instruction->getAddress()
<< "\n";
}
if(!ctx.getLabel(instruction->getAddress(), false).empty()){
std::cout << "\n\n; == FUNCTION " << ctx.getLabel(instruction->getAddress()) << " ==\n";
std::cout << "\n\n; ================ FUNCTION " << ctx.getLabel(instruction->getAddress()) << " ================\n";
}
std::cout << ctx.getInstructionString(*instruction);