fxos/lib/binary.cpp

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);
}