fxos/include/fxos/binary.h

214 lines
5.4 KiB
C++

//---------------------------------------------------------------------------//
// 1100101 |_ mov #0, r4 __ //
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
// |_ base# + offset |_| /_\_\___/__/ //
//---------------------------------------------------------------------------//
// fxos/binary: Main object for working with programs
//
// This header defines the main structures that combine to form the Binary
// object, which is the main access point for analyzing a program. The Binary
// structure references a VirtualSpace which emulates memory and can be used to
// read raw data. It then lists every Variable and Function that has been
// marked out in the program, either manually or by an analysis.
//---
#ifndef FXOS_BINARY_H
#define FXOS_BINARY_H
#include <fxos/util/types.h>
#include <fxos/util/bson.h>
#include <fxos/vspace.h>
#include <cassert>
#include <string>
#include <map>
namespace FxOS {
class OS;
struct BinaryObject;
struct Mark;
struct Variable;
struct Function;
struct Binary
{
/* Empty binary with an empty virtual space. */
Binary() = default;
BSON serialize() const;
void deserialize(BSON const &);
VirtualSpace &vspace()
{
return m_vspace;
}
VirtualSpace const &vspace() const
{
return m_vspace;
}
/* OS analysis (performed on-demand). Returns the new or cached OS
analysis results, nullptr if analysis failed. */
OS *OSAnalysis(bool force = false);
// TODO: Platform information in a binary
// TODO: Implement OS analysis
// TODO: Add and manage objects
std::map<u32, std::unique_ptr<BinaryObject>> const &objects() const
{
return m_objects;
}
private:
VirtualSpace m_vspace;
/* OS analysis results */
std::unique_ptr<OS> m_os;
/* All binary objects */
std::map<u32, std::unique_ptr<BinaryObject>> m_objects;
};
/* Base structure for all /binary objets/, ie. program objects that can be
declared in the program space. */
struct BinaryObject
{
enum Type : u8 { Mark, Variable, Function };
BinaryObject(Binary &binary, Type type, u32 address, u32 size):
m_binary {binary}, m_address {address}, m_size {size}, m_type {type}
{
}
/* Location and size in the address space. */
u32 address() const
{
return m_address;
}
u32 size() const
{
return m_size;
}
void setSize(u32 size)
{
m_size = size;
}
/* Binary that owns the object. */
Binary &parentBinary()
{
return m_binary;
}
Binary const &parentBinary() const
{
return m_binary;
}
/* Symbol name, no requirements on uniqueness or character set. */
std::string const &name() const
{
return m_name;
}
void setName(std::string const &name)
{
m_name = name;
}
/* User comment. */
std::string const &comment() const
{
return m_comment;
}
void setComment(std::string const &comment)
{
m_comment = comment;
}
/* Check for a non-empty intersection between two objects. */
bool intersects(BinaryObject const &other) const;
/* Check whether this object contains another object. */
bool contains(BinaryObject const &other) const;
/* User-readable string representation: "object <name> at <addr>" */
std::string str() const;
// TODO: BinaryObject serialization
/* Polymorphic accessors */
bool isMark() const
{
return m_type == Type::Mark;
}
bool isVariable() const
{
return m_type == Type::Variable;
}
bool isFunction() const
{
return m_type == Type::Function;
}
FxOS::Mark &getMark() const
{
assert(isMark() && "wrong BinaryObject accessor: not a Mark");
return *(FxOS::Mark *)this;
}
FxOS::Variable &getVariable() const
{
assert(isVariable() && "wrong BinaryObject accessor: not a Variable");
return *(FxOS::Variable *)this;
}
FxOS::Function &getFunction() const
{
assert(isFunction() && "wrong BinaryObject accessor: not a Function");
return *(FxOS::Function *)this;
}
private:
Binary &m_binary;
u32 m_address;
u32 m_size;
Type const m_type;
std::string m_name;
/* TODO: BinaryObject: don't reserve 32 bytes for empty comments */
std::string m_comment;
};
/* Basic, unattributed binary object used to mark out regions of code (eg.
"kernel", "timer driver", "LINK app", "zero", "interrupt handlers"...). May
alias with other binary objects. */
struct Mark: public BinaryObject
{
// TODO: Tags/colors in marks
// TODO: BinaryObject serialization
};
/* Binary object representing a non-empty piece of data. */
struct Variable: public BinaryObject
{
/* Create a new variable at the given location with the given name. The
type defaults to an unsigned machine word (u32). */
Variable(Binary &binary, u32 address, std::string const &name);
#if 0
DataType const *type() const
{
return m_type;
}
void setType(DataType const &type)
{
m_type = type;
BinaryObject::setSize(m_type.size());
}
private:
DataType const *m_type;
#endif
};
} /* namespace FxOS */
#endif /* FXOS_BINARY_H */