148 lines
4.4 KiB
C++
148 lines
4.4 KiB
C++
//---------------------------------------------------------------------------//
|
|
// 1100101 |_ mov #0, r4 __ //
|
|
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
|
|
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
|
|
// |_ base# + offset |_| /_\_\___/__/ //
|
|
//---------------------------------------------------------------------------//
|
|
|
|
#include <fxos/binary.h>
|
|
using namespace FxOS;
|
|
|
|
//=== Binary ===//
|
|
|
|
BSON Binary::serialize() const
|
|
{
|
|
BSONField *fields = (BSONField *)malloc(m_objects.size() * sizeof *fields);
|
|
int i = 0;
|
|
for(auto const &[address, obj]: m_objects) {
|
|
char str[32];
|
|
sprintf(str, "%08x", address);
|
|
// TODO: Serialize BinaryObjects
|
|
// new(&fields[i]) BSONField(str, obj->serialize());
|
|
new(&fields[i]) BSONField(str, BSON::mkNull());
|
|
i++;
|
|
}
|
|
|
|
return BSON::mkDocument({
|
|
{"*", BSON::mkString("Binary")},
|
|
{"vspace", m_vspace.serialize()},
|
|
{"objects", BSON::mkDocumentFromFieldArray(fields, m_objects.size())},
|
|
});
|
|
}
|
|
|
|
void Binary::deserialize(BSON const &b)
|
|
{
|
|
assert(b.isDocument() && b["*"].getString() == "Binary");
|
|
m_vspace.deserialize(b["vspace"]);
|
|
|
|
BSONField const *fields = b["objects"].getDocumentFields();
|
|
int N = b["objects"].size();
|
|
|
|
for(int i = 0; i < N; i++) {
|
|
uint32_t address = std::stoul(fields[i].getName(), nullptr, 16);
|
|
// TODO: Deserialize BinaryObject from fields[i].value()
|
|
}
|
|
}
|
|
|
|
OS *Binary::OSAnalysis(bool force) const
|
|
{
|
|
if(!m_os || force) {
|
|
/* We break constness a little bit here. We allow access to the OS
|
|
analysis for const Binary, even though it uses the VirtualSpace and
|
|
technically AbstractMemory allows implementations to modify the
|
|
memory in response to reads. */
|
|
m_os = std::make_unique<OS>(const_cast<VirtualSpace &>(m_vspace));
|
|
/* We don't keep an OS analysis result that failed */
|
|
if(m_os->type == OS::UNKNOWN)
|
|
m_os = nullptr;
|
|
}
|
|
return m_os.get();
|
|
}
|
|
|
|
std::optional<u32> Binary::objectAddress(std::string const &name) const
|
|
{
|
|
for(auto const &[address, obj]: m_objects) {
|
|
if(obj->name() == name)
|
|
return address;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
BinaryObject *Binary::objectAt(u32 address)
|
|
{
|
|
auto it = m_objects.find(address);
|
|
return (it == m_objects.end()) ? nullptr : it->second.get();
|
|
}
|
|
|
|
BinaryObject const *Binary::objectAt(u32 address) const
|
|
{
|
|
auto it = m_objects.find(address);
|
|
return (it == m_objects.end()) ? nullptr : it->second.get();
|
|
}
|
|
|
|
std::vector<BinaryObject *> Binary::objectsAt(u32 address)
|
|
{
|
|
std::vector<BinaryObject *> objects;
|
|
for(auto [it, end] = m_objects.equal_range(address); it != end; ++it)
|
|
objects.push_back(it->second.get());
|
|
return objects;
|
|
}
|
|
|
|
std::vector<BinaryObject const *> Binary::objectsAt(u32 address) const
|
|
{
|
|
std::vector<BinaryObject const *> objects;
|
|
for(auto [it, end] = m_objects.equal_range(address); it != end; ++it)
|
|
objects.push_back(it->second.get());
|
|
return objects;
|
|
}
|
|
|
|
std::vector<BinaryObject *> Binary::objectsCovering(u32 address)
|
|
{
|
|
std::vector<BinaryObject *> objects;
|
|
|
|
for(auto const &[obj_address, obj]: m_objects) {
|
|
if(obj_address <= address && obj_address + obj->size() < address)
|
|
objects.push_back(obj.get());
|
|
}
|
|
|
|
return objects;
|
|
}
|
|
|
|
std::vector<BinaryObject const *> Binary::objectsCovering(u32 address) const
|
|
{
|
|
std::vector<BinaryObject const *> objects;
|
|
|
|
for(auto const &[obj_address, obj]: m_objects) {
|
|
if(obj_address <= address && obj_address + obj->size() < address)
|
|
objects.push_back(obj.get());
|
|
}
|
|
|
|
return objects;
|
|
}
|
|
|
|
//=== BinaryObject ===//
|
|
|
|
bool BinaryObject::intersects(BinaryObject const &other) const
|
|
{
|
|
uint32_t inter_start = std::max(m_address, other.address());
|
|
uint32_t inter_end
|
|
= std::min(m_address + m_size, other.address() + other.size());
|
|
|
|
return inter_start < inter_end;
|
|
}
|
|
|
|
bool BinaryObject::contains(BinaryObject const &other) const
|
|
{
|
|
return m_address <= other.address()
|
|
&& m_address + m_size >= other.address() + other.size();
|
|
}
|
|
|
|
//=== Variable ===//
|
|
|
|
Variable::Variable(Binary &binary, u32 address, std::string const &name):
|
|
BinaryObject(binary, BinaryObject::Variable, address, 4)
|
|
{
|
|
setName(name);
|
|
// m_type = IntegerType(4, false);
|
|
}
|