summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-20 16:41:59 +0300
committerOxore <oxore@protonmail.com>2023-05-20 16:41:59 +0300
commit429d978d108dfb77665f0c03a7190e2754c8fa1f (patch)
tree057c0eb090a7f9592c91ba9778795034e06bcd0f /main.cpp
parentd9136afc4a89ad26663e18afd61683dd9dae523f (diff)
Impl marks referencing for MOVE and MOVEA
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp96
1 files changed, 70 insertions, 26 deletions
diff --git a/main.cpp b/main.cpp
index 3a4e34a..4f10d03 100644
--- a/main.cpp
+++ b/main.cpp
@@ -28,6 +28,12 @@ class DisasmMap {
DisasmNode *_map[kDisasmMapSizeElements]{};
DisasmNode *findNodeByOffset(uint32_t offset) const;
DisasmNode *insertTracedNode(uint32_t offset, TracedNodeType);
+ void insertReferencedBy(
+ const uint32_t by_addr,
+ const uint32_t ref_addr,
+ const TracedNodeType type,
+ const DataBuffer &code,
+ const ReferenceType ref_type);
bool canBeAllocated(const DisasmNode& node) const;
public:
const DisasmNode *FindNodeByOffset(uint32_t offset) const
@@ -78,6 +84,27 @@ DisasmNode *DisasmMap::insertTracedNode(const uint32_t offset, const TracedNodeT
return node;
}
+void DisasmMap::insertReferencedBy(
+ const uint32_t by_addr,
+ const uint32_t ref_addr,
+ const TracedNodeType type,
+ const DataBuffer &code,
+ const ReferenceType ref_type)
+{
+ auto *const ref_node = insertTracedNode(ref_addr, type);
+ const auto size = ref_node->Disasm(code);
+ assert(size >= kInstructionSizeStepBytes);
+ if (canBeAllocated(*ref_node)) {
+ // Spread across the size
+ for (size_t o = kInstructionSizeStepBytes; o < size; o++) {
+ _map[(ref_node->offset + o) / kInstructionSizeStepBytes] = ref_node;
+ }
+ } else {
+ ref_node->DisasmAsRaw(code);
+ }
+ ref_node->AddReferencedBy(by_addr, ref_type);
+}
+
bool DisasmMap::canBeAllocated(const DisasmNode& node) const
{
const auto size = node.size / kInstructionSizeStepBytes;
@@ -91,6 +118,28 @@ bool DisasmMap::canBeAllocated(const DisasmNode& node) const
return true;
}
+static ReferenceType ReferenceTypeFromRefKindMask1(const RefKindMask ref_kinds)
+{
+ return (ref_kinds & kRefCallMask)
+ ? ReferenceType::kCall
+ : (ref_kinds & kRef1ReadMask)
+ ? ReferenceType::kRead
+ : (ref_kinds & kRef1WriteMask)
+ ? ReferenceType::kWrite
+ : ReferenceType::kBranch;
+}
+
+static ReferenceType ReferenceTypeFromRefKindMask2(const RefKindMask ref_kinds)
+{
+ return (ref_kinds & kRefCallMask)
+ ? ReferenceType::kCall
+ : (ref_kinds & kRef2ReadMask)
+ ? ReferenceType::kRead
+ : (ref_kinds & kRef2WriteMask)
+ ? ReferenceType::kWrite
+ : ReferenceType::kBranch;
+}
+
void DisasmMap::Disasm(const DataBuffer &code, const Settings &)
{
DisasmNode *node;
@@ -115,32 +164,21 @@ void DisasmMap::Disasm(const DataBuffer &code, const Settings &)
node->DisasmAsRaw(code);
}
// FIXME implement deep graph walk for DisasmMapType::kTraced case
- const bool has_code_ref =
- ((node->ref_kinds & kRef1Mask) && node->ref1_addr < code.occupied_size) ||
+ const bool has_code_ref1 =
+ ((node->ref_kinds & kRef1Mask) && node->ref1_addr < code.occupied_size);
+ if (has_code_ref1) {
+ const TracedNodeType type = (node->ref_kinds & (kRef1ReadMask | kRef1WriteMask))
+ ? TracedNodeType::kData : TracedNodeType::kInstruction;
+ const auto ref_type = ReferenceTypeFromRefKindMask1(node->ref_kinds);
+ insertReferencedBy(node->offset, node->ref1_addr, type, code, ref_type);
+ }
+ const bool has_code_ref2 =
((node->ref_kinds & kRef2Mask) && node->ref2_addr < code.occupied_size);
- if (has_code_ref) {
- const uint32_t ref_addr = (node->ref_kinds & kRef1Mask) ? node->ref1_addr : node->ref2_addr;
- const TracedNodeType type = (node->ref_kinds & (kRefReadMask | kRefWriteMask))
+ if (has_code_ref2) {
+ const TracedNodeType type = (node->ref_kinds & (kRef2ReadMask | kRef2WriteMask))
? TracedNodeType::kData : TracedNodeType::kInstruction;
- auto *const ref_node = insertTracedNode(ref_addr, type);
- const auto size = ref_node->Disasm(code);
- assert(size >= kInstructionSizeStepBytes);
- if (canBeAllocated(*ref_node)) {
- // Spread across the size
- for (size_t o = kInstructionSizeStepBytes; o < size; o++) {
- _map[(ref_node->offset + o) / kInstructionSizeStepBytes] = ref_node;
- }
- } else {
- ref_node->DisasmAsRaw(code);
- }
- const auto ref_type = (node->ref_kinds & kRefCallMask)
- ? ReferenceType::kCall
- : (node->ref_kinds & kRefReadMask)
- ? ReferenceType::kRead
- : (node->ref_kinds & kRefWriteMask)
- ? ReferenceType::kWrite
- : ReferenceType::kBranch;
- ref_node->AddReferencedBy(node->offset, ref_type);
+ const auto ref_type = ReferenceTypeFromRefKindMask2(node->ref_kinds);
+ insertReferencedBy(node->offset, node->ref2_addr, type, code, ref_type);
}
i += node->size;
}
@@ -255,8 +293,14 @@ static void RenderDisassembly(
const uint32_t ref2_addr = (with_ref && ref2) ? ref2->offset : 0;
if (with_ref && (ref1 || ref2)) {
const RefKindMask ref_kinds =
- ((s.abs_marks ? (node->ref_kinds & kRefAbsMask) : 0) |
- (s.rel_marks ? (node->ref_kinds & kRefRelMask) : 0));
+ (s.abs_marks
+ ? ((ref1 ? (node->ref_kinds & kRef1AbsMask) : 0) |
+ (ref2 ? (node->ref_kinds & kRef2AbsMask) : 0))
+ : 0) |
+ (s.rel_marks
+ ? ((ref1 ? (node->ref_kinds & kRef1RelMask) : 0) |
+ (ref2 ? (node->ref_kinds & kRef2RelMask) : 0))
+ : 0);
node->op.FPrint(output, ref_kinds, node->offset, ref1_addr, ref2_addr);
if (s.xrefs_to && ref1) {
char ref_addr_str[12]{};