diff options
Diffstat (limited to 'Database')
-rw-r--r-- | Database/database-types.h | 94 | ||||
-rw-r--r-- | Database/internals/database-internal.cpp | 54 | ||||
-rw-r--r-- | Database/internals/database-internal.h | 78 | ||||
-rw-r--r-- | Database/internals/database-references.cpp | 94 | ||||
-rw-r--r-- | Database/internals/database-references.h | 116 | ||||
-rw-r--r-- | Database/internals/database-segment.cpp | 238 | ||||
-rw-r--r-- | Database/internals/database-segment.h | 144 |
7 files changed, 409 insertions, 409 deletions
diff --git a/Database/database-types.h b/Database/database-types.h index 95c5ebd..7d92f87 100644 --- a/Database/database-types.h +++ b/Database/database-types.h @@ -1,47 +1,47 @@ -#ifndef __DATABASE_TYPES_H__
-#define __DATABASE_TYPES_H__
-
-/** The basic tags that describe the bytes of the database. The tag "CODE_FIRST_BYTE" is
- * mainly for multi-bytes instructions, in order to help the UI displaying
- * properly the instructions.
- */
-
-enum basic_tags_t {
- TAG_UNKNOWN = 0,
- TAG_CODE,
- TAG_DATA,
- TAG_CODE_FIRST_BYTE,
-};
-
-/** The 8-bits tag for a byte. The certitude part
- * A non-hollow database will be as big (at least) as the input file: in-memory-RLE is probably a good idea.
- */
-struct memory_tags_t {
- unsigned short basic_tags: 2;
- /** -1..30, 30 being "user hinted", 29 being "external reference" (entry point, exported symbol, ...)
- * and -1 means something's fishy with that tag, and that it is probably completely wrong.
- * Certitude will grow down with distance from a certain piece of info when the crawler goes away jumping around.
- */
- unsigned short certitude: 6;
-};
-
-/** An absolute pointer can reference a segment from its ID, and a pointer within the segment.
- */
-
-typedef union {
- Uint64 raw_ptr;
- struct {
- Uint32 segment_id;
- Uint32 ptr;
- };
-} absolute_ptr;
-
-/** A function description.
- */
-
-struct function_t {
- absolute_ptr start;
- Uint32 size;
-};
-
-#endif
+#ifndef __DATABASE_TYPES_H__ +#define __DATABASE_TYPES_H__ + +/** The basic tags that describe the bytes of the database. The tag "CODE_FIRST_BYTE" is + * mainly for multi-bytes instructions, in order to help the UI displaying + * properly the instructions. + */ + +enum basic_tags_t { + TAG_UNKNOWN = 0, + TAG_CODE, + TAG_DATA, + TAG_CODE_FIRST_BYTE, +}; + +/** The 8-bits tag for a byte. The certitude part + * A non-hollow database will be as big (at least) as the input file: in-memory-RLE is probably a good idea. + */ +struct memory_tags_t { + unsigned short basic_tags: 2; + /** -1..30, 30 being "user hinted", 29 being "external reference" (entry point, exported symbol, ...) + * and -1 means something's fishy with that tag, and that it is probably completely wrong. + * Certitude will grow down with distance from a certain piece of info when the crawler goes away jumping around. + */ + unsigned short certitude: 6; +}; + +/** An absolute pointer can reference a segment from its ID, and a pointer within the segment. + */ + +typedef union { + Uint64 raw_ptr; + struct { + Uint32 segment_id; + Uint32 ptr; + }; +} absolute_ptr; + +/** A function description. + */ + +struct function_t { + absolute_ptr start; + Uint32 size; +}; + +#endif diff --git a/Database/internals/database-internal.cpp b/Database/internals/database-internal.cpp index 0c90b71..e19222a 100644 --- a/Database/internals/database-internal.cpp +++ b/Database/internals/database-internal.cpp @@ -1,27 +1,27 @@ -#include "database-internal.h"
-
-DatabaseCell::DatabaseCell(Cpu * cpu, Uint64 cpu_base, absolute_ptr origin, Uint32 size, Uint32 extra_size, DatabaseCell * prev, Database * parent) : cpu(cpu), next(0), prev(prev), parent(parent) {
- prev->next = this;
- parent->setEnd(this);
- if (origin) {
- Segment * origin_seg = parent->GetSegment(SEGID(origin));
- segment = new Segment(size, cpu_base, parent->GetNextSegId(), extra_size, origin_seg->getPristineMemory() + SEGOFFSET(origin));
- } else {
- segment = new Segment(size, cpu_base, parent->GetNextSegId(), extra_size);
- }
-}
-
-DatabaseCell::~DatabaseCell() {
- if (parent->getEnd() == this)
- parent->setEnd(prev);
-
- if (parent->getStart() == this)
- parent->setStart(next);
-
- if (next)
- next->prev = prev;
- if (prev)
- prev->next = next;
-
- delete segment;
-}
+#include "database-internal.h" + +DatabaseCell::DatabaseCell(Cpu * cpu, Uint64 cpu_base, absolute_ptr origin, Uint32 size, Uint32 extra_size, DatabaseCell * prev, Database * parent) : cpu(cpu), next(0), prev(prev), parent(parent) { + prev->next = this; + parent->setEnd(this); + if (origin) { + Segment * origin_seg = parent->GetSegment(SEGID(origin)); + segment = new Segment(size, cpu_base, parent->GetNextSegId(), extra_size, origin_seg->getPristineMemory() + SEGOFFSET(origin)); + } else { + segment = new Segment(size, cpu_base, parent->GetNextSegId(), extra_size); + } +} + +DatabaseCell::~DatabaseCell() { + if (parent->getEnd() == this) + parent->setEnd(prev); + + if (parent->getStart() == this) + parent->setStart(next); + + if (next) + next->prev = prev; + if (prev) + prev->next = next; + + delete segment; +} diff --git a/Database/internals/database-internal.h b/Database/internals/database-internal.h index 75e82c9..f63b40e 100644 --- a/Database/internals/database-internal.h +++ b/Database/internals/database-internal.h @@ -1,39 +1,39 @@ -#ifndef __DATABASE_INTERNAL_H__
-#define __DATABASE_INTERNAL_H__
-
-#include "database-segment.h"
-#include "database-types.h"
-
-class Database;
-class Cpu;
-
-/** A database element. Basically, the database is a collection of segments, associated with information.
- * This class could have been merged with Segment's, but in an effort to split the segment, that only
- * contains the raw memory, and the various data associated with it, this glue element exists. It'll also
- * construct a linked list for the database.
- */
-
-class DatabaseCell : public Base {
- public:
- /** The constructor of a DatabaseCell. Note that if you specify the origin parameter,
- * it'll create a sub-segment based on the first one. Note also that this doesn't support
- * the patching system, yet.
- */
- DatabaseCell(Cpu * cpu, Uint64 cpu_base, absolute_ptr origin, Uint32 size, Uint32 extra_size, DatabaseCell * prev);
- ~DatabaseCell();
- Uint32 getID() { return segment->GetID(); }
- void LoadMemory(Handle * src) { segment->LoadMemory(src); }
- Segment * getSegment() { return segment; }
- Cpu * getCpu() { return cpu; }
- Uint64 getCpuBase() { return segment->getCpuBase(); }
- absolute_ptr getOrigin() { return origin; }
-
- private:
- Segment * segment;
- Cpu * cpu;
- absolute_ptr origin; // a data segment can come from within another one
- DatabaseCell * next, * prev;
- Database * parent;
-};
-
-#endif
+#ifndef __DATABASE_INTERNAL_H__ +#define __DATABASE_INTERNAL_H__ + +#include "database-segment.h" +#include "database-types.h" + +class Database; +class Cpu; + +/** A database element. Basically, the database is a collection of segments, associated with information. + * This class could have been merged with Segment's, but in an effort to split the segment, that only + * contains the raw memory, and the various data associated with it, this glue element exists. It'll also + * construct a linked list for the database. + */ + +class DatabaseCell : public Base { + public: + /** The constructor of a DatabaseCell. Note that if you specify the origin parameter, + * it'll create a sub-segment based on the first one. Note also that this doesn't support + * the patching system, yet. + */ + DatabaseCell(Cpu * cpu, Uint64 cpu_base, absolute_ptr origin, Uint32 size, Uint32 extra_size, DatabaseCell * prev); + ~DatabaseCell(); + Uint32 getID() { return segment->GetID(); } + void LoadMemory(Handle * src) { segment->LoadMemory(src); } + Segment * getSegment() { return segment; } + Cpu * getCpu() { return cpu; } + Uint64 getCpuBase() { return segment->getCpuBase(); } + absolute_ptr getOrigin() { return origin; } + + private: + Segment * segment; + Cpu * cpu; + absolute_ptr origin; // a data segment can come from within another one + DatabaseCell * next, * prev; + Database * parent; +}; + +#endif diff --git a/Database/internals/database-references.cpp b/Database/internals/database-references.cpp index 8520f16..c138698 100644 --- a/Database/internals/database-references.cpp +++ b/Database/internals/database-references.cpp @@ -1,47 +1,47 @@ -#include "database-references.h"
-
-RefFrom::RefFrom(RefTo * refTo, SegmentRefData * data) : refTo(refTo), data(data) {
- assert(refto);
- assert(data);
-
- next = data->getRefFrom();
- prev = 0;
- data->firstRefFrom = this;
- if (next)
- next->prev = this;
-}
-
-RefFrom::~RefFrom() {
- if (next)
- next->prev = prev;
- if (prev)
- prev->next = next;
- else
- data->setFirstRefFrom(next);
-}
-
-RefTo::RefTo(absolute_ptr ptr, SegmentRefData * data, Database * database) : data(data) {
- assert(database);
- Segment * destSeg = database->getSegment(ptr.segment_id);
- assert(destSeg);
- refFrom = new RefFrom(this, destSeg->getSegmentRefData(ptr.ptr);
-
- RefTo * t = data->getRefTo();
- if (t) {
- delete t;
- data->setRefTo(this);
- }
-}
-
-RefTo::~RefTo() {
- data->refTo = 0;
- delete refFrom;
-}
-
-SegmentRefData::SegmentRefData(Uint32 ptr, Segment * seg) : ptr(ptr), seg(seg) {
- seg->setSegmentRefData(ptr, this);
-}
-
-SegmentRefData::~SegmentRefData() {
- seg->setSegmentRefData(ptr, 0);
-}
+#include "database-references.h" + +RefFrom::RefFrom(RefTo * refTo, SegmentRefData * data) : refTo(refTo), data(data) { + assert(refto); + assert(data); + + next = data->getRefFrom(); + prev = 0; + data->firstRefFrom = this; + if (next) + next->prev = this; +} + +RefFrom::~RefFrom() { + if (next) + next->prev = prev; + if (prev) + prev->next = next; + else + data->setFirstRefFrom(next); +} + +RefTo::RefTo(absolute_ptr ptr, SegmentRefData * data, Database * database) : data(data) { + assert(database); + Segment * destSeg = database->getSegment(ptr.segment_id); + assert(destSeg); + refFrom = new RefFrom(this, destSeg->getSegmentRefData(ptr.ptr); + + RefTo * t = data->getRefTo(); + if (t) { + delete t; + data->setRefTo(this); + } +} + +RefTo::~RefTo() { + data->refTo = 0; + delete refFrom; +} + +SegmentRefData::SegmentRefData(Uint32 ptr, Segment * seg) : ptr(ptr), seg(seg) { + seg->setSegmentRefData(ptr, this); +} + +SegmentRefData::~SegmentRefData() { + seg->setSegmentRefData(ptr, 0); +} diff --git a/Database/internals/database-references.h b/Database/internals/database-references.h index 65e4cdf..278b531 100644 --- a/Database/internals/database-references.h +++ b/Database/internals/database-references.h @@ -1,58 +1,58 @@ -#ifndef __DATABASE_REFERENCES_H__
-#define __DATABASE_REFERENCES_H__
-
-class SegmentData;
-class RefFrom;
-class RefTo;
-
-/** The reference system, where the database will be able to hold references from and to memory pointers.
- */
-
-class RefFrom : public Base {
- public:
- RefFrom(RefTo * refTo, SegmentRefData * data);
- ~RefFrom()
- SegmentRefData * getRefSegData() { return refTo->getSegRefData(); }
- SegmentRefData * getSegRefData() { return data; }
- RefFrom * getNext() { return next; }
- private:
- RefTo * refTo;
- RefFrom * next, * prev;
- SegmentRefData * data;
-};
-
-class RefTo : public Base {
- public:
- RefTo(Uint32 ptr, SegmentRefData * data);
- ~RefTo();
- SegmentRefData * getRefSegData() { return refFrom->getSegRefData(); }
- SegmentRefData * getSegRefData() { return data; }
- private:
- RefFrom * refFrom;
- SegmentRefData * data;
-};
-
-class SegmentRefData : public Base {
- public:
- SegmentRefData(Uint32 ptr, Segment * seg);
- ~SegmentRefData()
- Uint32 getPtr() { return ptr; }
- Segment * getSegment() { return seg; }
- SegmentRefData * getSegmentRefData(Uint32 ptr) { return seg->getSegmentRefData(ptr); }
-
- RefTo * getRefTo() { return refTo; }
- RefFrom * getRefFrom() { return firstRefFrom; }
-
- void setRefTo(RefTo * newRefTo) { refTo = newRefTo; checkDestroy(); }
- void setFirstRefFrom(RefFrom * newFirstRefFrom) { firstRefFrom = newFirstRefFrom; checkDestroy(); }
-
- private:
- RefTo * refTo;
- RefFrom * firstRefFrom;
-
- Uint32 ptr;
- Segment * seg;
- void checkDestroy() { if (!refTo && !firstRefFrom) delete this; }
-};
-
-#endif
+#ifndef __DATABASE_REFERENCES_H__ +#define __DATABASE_REFERENCES_H__ + +class SegmentData; +class RefFrom; +class RefTo; + +/** The reference system, where the database will be able to hold references from and to memory pointers. + */ + +class RefFrom : public Base { + public: + RefFrom(RefTo * refTo, SegmentRefData * data); + ~RefFrom() + SegmentRefData * getRefSegData() { return refTo->getSegRefData(); } + SegmentRefData * getSegRefData() { return data; } + RefFrom * getNext() { return next; } + private: + RefTo * refTo; + RefFrom * next, * prev; + SegmentRefData * data; +}; + +class RefTo : public Base { + public: + RefTo(Uint32 ptr, SegmentRefData * data); + ~RefTo(); + SegmentRefData * getRefSegData() { return refFrom->getSegRefData(); } + SegmentRefData * getSegRefData() { return data; } + private: + RefFrom * refFrom; + SegmentRefData * data; +}; + +class SegmentRefData : public Base { + public: + SegmentRefData(Uint32 ptr, Segment * seg); + ~SegmentRefData() + Uint32 getPtr() { return ptr; } + Segment * getSegment() { return seg; } + SegmentRefData * getSegmentRefData(Uint32 ptr) { return seg->getSegmentRefData(ptr); } + + RefTo * getRefTo() { return refTo; } + RefFrom * getRefFrom() { return firstRefFrom; } + + void setRefTo(RefTo * newRefTo) { refTo = newRefTo; checkDestroy(); } + void setFirstRefFrom(RefFrom * newFirstRefFrom) { firstRefFrom = newFirstRefFrom; checkDestroy(); } + + private: + RefTo * refTo; + RefFrom * firstRefFrom; + + Uint32 ptr; + Segment * seg; + void checkDestroy() { if (!refTo && !firstRefFrom) delete this; } +}; + +#endif diff --git a/Database/internals/database-segment.cpp b/Database/internals/database-segment.cpp index 4b94000..55689f8 100644 --- a/Database/internals/database-segment.cpp +++ b/Database/internals/database-segment.cpp @@ -1,119 +1,119 @@ -#include "database-segment.h"
-
-Segment::Segment(Uint32 size, Uint32 id, Uint64 cpu_base, Uint32 extra_size, const Byte * data) : patches(0), plainmemory(0), size(size), extra_size(extra_size), id(id), cpu_base(cpu_base) {
- Uint64 fullsize = size + extra_size;
-
- assert(size);
-
- if (data) {
- plainmemory = (Byte *) data;
- loaded = true;
- allocated = false
- } else {
- plainmemory = Allocator<Byte>::alloc(size);
- loaded = false;
- allocated = true;
- }
- tags = Allocator<memory_tags_t>::alloc(fullsize);
- refData = Allocator<SegmentRefData *>::alloc(fullsize);
-}
-
-Segment::~Segment() {
- if (allocated)
- Allocator<Byte>::free(plainmemory);
- if (patches)
- Allocator<Byte>::free(patches);
- if (patchesmemory)
- Allocator<Byte>::free(patchesmap);
- Allocator<memory_tags_t>::free(tags);
- Allocator<SegmentRefData *>::free(refData);
-}
-
-short Segment::Read(Uint32 ptr) {
- if (ptr >= size) {
- LOG(CONSOLE, ERROR, "Out of bound read attempt in segment %i at %08X\n", id, ptr);
- return -1;
- }
- if (IsPatched(ptr))
- return patches[ptr];
- return plainmemory[ptr];
-}
-
-short Segment::RawRead(Uint32 ptr) {
- if (ptr >= size) {
- LOG(CONSOLE, ERROR, "Out of bound rawread attempt in segment %i at %08X\n", id, ptr);
- return -1;
- }
- return plainmemory[ptr];
-}
-
-void Segment::Patch(Uint32 ptr, Byte val) {
- if (!patchesmap) {
- patches = Allocator<Byte>::alloc(size);
- patchesmap = Allocator<Byte>::alloc((size << 3) + ((size & 7) ? 1 : 0));
- }
- if (ptr >= size) {
- LOG(CONSOLE, ERROR, "Out of bound patch attempt in segment %i at %08X\n", id, ptr);
- return;
- }
- patches[ptr] = val;
- patchesmap[ptr / 8] |= (1 << ptr % 8);
-}
-
-void Segment::Restore(Uint32 ptr) {
- if (!patchesmap)
- return;
- if (ptr >= size) {
- LOG(CONSOLE, ERROR, "Out of bound patch attempt in segment %i at %08X\n", id, ptr);
- return;
- }
- patchesmap[ptr / 8] &= ~(1 << (ptr % 8));
-}
-
-bool Segment::IsPatched(Uint32 ptr) {
- if (!patchesmap)
- return false;
- return patchesmap[ptr / 8] & (1 << (ptr % 8));
-}
-
-void Segment::LoadMemory(Handle * src) {
- if (loaded) {
- LOG(CONSOLE, WARNING, "Memory segment already loaded, second attempt ignored.");
- return;
- }
-
- src->Read(plainmemory, size);
-}
-
-void setTag(Uint32 ptr, memory_tags_t tag) {
- if (ptr >= (size + extra_size)) {
- LOG(CONSOLE, ERROR, "Out of bound setTag attempt in segment %i at %08X\n", id, ptr);
- return;
- }
- tags[ptr] = tag;
-}
-
-memory_tags_t getTag(Uint32 ptr) {
- if (ptr >= (size + extra_size)) {
- memory_tags_t z = { 0, 0 };
- LOG(CONSOLE, ERROR, "Out of bound getTag attempt in segment %i at %08X\n", id, ptr);
- return z;
- }
- return tags[ptr];
-}
-
-SegmentRefData * Segment::getSegmentRefData(Uint32 ptr) {
- if (ptr >= (size + extra_size)) {
- LOG(CONSOLE, ERROR, "Out of bound getSegmentRefData attempt in segment %i at %08X\n", id, ptr);
- return 0;
- }
- return refData[ptr];
-}
-
-void Segment::setSegmentRefData(Uint32 ptr, SegmentRefData * data) {
- if (ptr >= (size + extra_size)) {
- LOG(CONSOLE, ERROR, "Out of bound setSegmentRefData attempt in segment %i at %08X\n", id, ptr);
- return;
- }
- refData[ptr] = data;
-}
+#include "database-segment.h" + +Segment::Segment(Uint32 size, Uint32 id, Uint64 cpu_base, Uint32 extra_size, const Byte * data) : patches(0), plainmemory(0), size(size), extra_size(extra_size), id(id), cpu_base(cpu_base) { + Uint64 fullsize = size + extra_size; + + assert(size); + + if (data) { + plainmemory = (Byte *) data; + loaded = true; + allocated = false + } else { + plainmemory = Allocator<Byte>::alloc(size); + loaded = false; + allocated = true; + } + tags = Allocator<memory_tags_t>::alloc(fullsize); + refData = Allocator<SegmentRefData *>::alloc(fullsize); +} + +Segment::~Segment() { + if (allocated) + Allocator<Byte>::free(plainmemory); + if (patches) + Allocator<Byte>::free(patches); + if (patchesmemory) + Allocator<Byte>::free(patchesmap); + Allocator<memory_tags_t>::free(tags); + Allocator<SegmentRefData *>::free(refData); +} + +short Segment::Read(Uint32 ptr) { + if (ptr >= size) { + LOG(CONSOLE, ERROR, "Out of bound read attempt in segment %i at %08X\n", id, ptr); + return -1; + } + if (IsPatched(ptr)) + return patches[ptr]; + return plainmemory[ptr]; +} + +short Segment::RawRead(Uint32 ptr) { + if (ptr >= size) { + LOG(CONSOLE, ERROR, "Out of bound rawread attempt in segment %i at %08X\n", id, ptr); + return -1; + } + return plainmemory[ptr]; +} + +void Segment::Patch(Uint32 ptr, Byte val) { + if (!patchesmap) { + patches = Allocator<Byte>::alloc(size); + patchesmap = Allocator<Byte>::alloc((size << 3) + ((size & 7) ? 1 : 0)); + } + if (ptr >= size) { + LOG(CONSOLE, ERROR, "Out of bound patch attempt in segment %i at %08X\n", id, ptr); + return; + } + patches[ptr] = val; + patchesmap[ptr / 8] |= (1 << ptr % 8); +} + +void Segment::Restore(Uint32 ptr) { + if (!patchesmap) + return; + if (ptr >= size) { + LOG(CONSOLE, ERROR, "Out of bound patch attempt in segment %i at %08X\n", id, ptr); + return; + } + patchesmap[ptr / 8] &= ~(1 << (ptr % 8)); +} + +bool Segment::IsPatched(Uint32 ptr) { + if (!patchesmap) + return false; + return patchesmap[ptr / 8] & (1 << (ptr % 8)); +} + +void Segment::LoadMemory(Handle * src) { + if (loaded) { + LOG(CONSOLE, WARNING, "Memory segment already loaded, second attempt ignored."); + return; + } + + src->Read(plainmemory, size); +} + +void setTag(Uint32 ptr, memory_tags_t tag) { + if (ptr >= (size + extra_size)) { + LOG(CONSOLE, ERROR, "Out of bound setTag attempt in segment %i at %08X\n", id, ptr); + return; + } + tags[ptr] = tag; +} + +memory_tags_t getTag(Uint32 ptr) { + if (ptr >= (size + extra_size)) { + memory_tags_t z = { 0, 0 }; + LOG(CONSOLE, ERROR, "Out of bound getTag attempt in segment %i at %08X\n", id, ptr); + return z; + } + return tags[ptr]; +} + +SegmentRefData * Segment::getSegmentRefData(Uint32 ptr) { + if (ptr >= (size + extra_size)) { + LOG(CONSOLE, ERROR, "Out of bound getSegmentRefData attempt in segment %i at %08X\n", id, ptr); + return 0; + } + return refData[ptr]; +} + +void Segment::setSegmentRefData(Uint32 ptr, SegmentRefData * data) { + if (ptr >= (size + extra_size)) { + LOG(CONSOLE, ERROR, "Out of bound setSegmentRefData attempt in segment %i at %08X\n", id, ptr); + return; + } + refData[ptr] = data; +} diff --git a/Database/internals/database-segment.h b/Database/internals/database-segment.h index 72086a7..a08b149 100644 --- a/Database/internals/database-segment.h +++ b/Database/internals/database-segment.h @@ -1,72 +1,72 @@ -#ifndef __DATABASE_SEGMENT_H__
-#define __DATABASE_SEGMENT_H__
-
-#include "database-types.h"
-
-class SegmentRefData;
-
-/**
- * The Segment class that holds the memory and patches for a memory segment.
- *
- * This class will passively hold the memory for a segment memory. The tags
- * corresponding to each byte are also stored there. The patches are optionnal,
- * and will only be allocated if a patch is actually done.
- *
- * TODO: do in-memory hollow structure for the tags.
- */
-
-class Segment : public Base {
- public:
- /**
- * Main constructor.
- *
- * @param size is the real data size of this segment.
- * @param id is the static id for that data segment.
- * @param cpu_base is the base absolute physical address for that segment in the cpu's flat memory.
- * @param extra_size gives the size of the uninitialized memory at the end of the segment, typically the bss part.
- * @param data optionally holds the memory to use for this segment. If it's provided, the caller MUST NOT free it, as it's going to be used directly.
- */
- Segment(Uint32 size, Uint32 id, Uint64 cpu_base, Uint32 extra_size = 0, const Byte * data = 0);
- ~Segment();
- Uint32 getId() { return id; }
- /** Will return the byte for that pointer in the segment. May be patched.
- * @param ptr is the pointer for the byte to be retrieved.
- * @return the byte read, or -1 if it's inside the BSS part, or outside the whole segment.
- */
- short Read(Uint32 ptr);
- /** Will return the byte for that pointer in the segment. Will NOT be patched.
- * @param ptr is the pointer for the byte to be retrieved.
- * @return the byte read, or -1 if it's inside the BSS part, or outside the whole segment.
- */
- short RawRead(Uint32 ptr);
- /** In case you need to read the (unpatched) memory block.
- * @return the memory block of the segment.
- */
- const Byte * getPristineMemory() { return plainmemory; }
- void Patch(Uint32 ptr, Byte val);
- void Restore(Uint32 ptr);
- bool IsPatched(Uint32 ptr);
- bool IsLoaded() { return loaded; }
- /** Will load the memory segment with the provided Handle; will
- * only work if you didn't provide data during the constructor.
- * @see Segment()
- */
- void LoadMemory(Handle * src);
- void setTag(Uint32 ptr, memory_tags_t tag);
- memory_tags_t getTag(Uint32 ptr);
- Uint32 getSize() { return size; }
- Uint64 getFullSize() { return size + extra_size; }
- Uint64 getCpuBase() { return cpu_base; }
- SegmentRefData * getSegmentRefData(Uint32 ptr);
- void setSegmentRefData(Uint32 ptr, SegmentRefData * data);
- private:
- Byte * plainmemory, * patches, * patchesmap;
- SegmentRefData ** refData;
- memory_tags_t * tags;
- bool loaded, allocated;
- Uint32 size, extra_size;
- Uint32 id;
- Uint64 cpu_base;
-}
-
-#endif
+#ifndef __DATABASE_SEGMENT_H__ +#define __DATABASE_SEGMENT_H__ + +#include "database-types.h" + +class SegmentRefData; + +/** + * The Segment class that holds the memory and patches for a memory segment. + * + * This class will passively hold the memory for a segment memory. The tags + * corresponding to each byte are also stored there. The patches are optionnal, + * and will only be allocated if a patch is actually done. + * + * TODO: do in-memory hollow structure for the tags. + */ + +class Segment : public Base { + public: + /** + * Main constructor. + * + * @param size is the real data size of this segment. + * @param id is the static id for that data segment. + * @param cpu_base is the base absolute physical address for that segment in the cpu's flat memory. + * @param extra_size gives the size of the uninitialized memory at the end of the segment, typically the bss part. + * @param data optionally holds the memory to use for this segment. If it's provided, the caller MUST NOT free it, as it's going to be used directly. + */ + Segment(Uint32 size, Uint32 id, Uint64 cpu_base, Uint32 extra_size = 0, const Byte * data = 0); + ~Segment(); + Uint32 getId() { return id; } + /** Will return the byte for that pointer in the segment. May be patched. + * @param ptr is the pointer for the byte to be retrieved. + * @return the byte read, or -1 if it's inside the BSS part, or outside the whole segment. + */ + short Read(Uint32 ptr); + /** Will return the byte for that pointer in the segment. Will NOT be patched. + * @param ptr is the pointer for the byte to be retrieved. + * @return the byte read, or -1 if it's inside the BSS part, or outside the whole segment. + */ + short RawRead(Uint32 ptr); + /** In case you need to read the (unpatched) memory block. + * @return the memory block of the segment. + */ + const Byte * getPristineMemory() { return plainmemory; } + void Patch(Uint32 ptr, Byte val); + void Restore(Uint32 ptr); + bool IsPatched(Uint32 ptr); + bool IsLoaded() { return loaded; } + /** Will load the memory segment with the provided Handle; will + * only work if you didn't provide data during the constructor. + * @see Segment() + */ + void LoadMemory(Handle * src); + void setTag(Uint32 ptr, memory_tags_t tag); + memory_tags_t getTag(Uint32 ptr); + Uint32 getSize() { return size; } + Uint64 getFullSize() { return size + extra_size; } + Uint64 getCpuBase() { return cpu_base; } + SegmentRefData * getSegmentRefData(Uint32 ptr); + void setSegmentRefData(Uint32 ptr, SegmentRefData * data); + private: + Byte * plainmemory, * patches, * patchesmap; + SegmentRefData ** refData; + memory_tags_t * tags; + bool loaded, allocated; + Uint32 size, extra_size; + Uint32 id; + Uint64 cpu_base; +} + +#endif |